我想写一个方法,如果集合为空则返回None
,在其他情况下返回Some(collection)
。
我能得到的最好的是
implicit class CollectionExtensions[A, Repr](self: TraversableLike[A, Repr]){
def toOption: Option[Repr] = if (self.nonEmpty) Some(self.asInstanceOf[Repr]) else None
}
但是转换 .asInstanceOf[Repr]
似乎是错误的。正确的做法是什么?
最佳答案
除了@dk14 回答之外,您还可以使用其他一些方法:
为
Repr with TraversableOnce[A]
使用隐式类。这也将支持Iterator
,因为Iterator
扩展TraversableOnce
,但不扩展TraversableLike
。implicit class CollectionExtensions[A, Repr](val self: Repr with TraversableOnce[A]) extends AnyVal { def toOption: Option[Repr] = if (self.nonEmpty) Some(self) else None }
仅为
Repr
使用隐式类,但要求证明它可以隐式转换为Traversable
。这种方法还支持Array
和String
,因为它们根本不扩展Traversable
,但可以隐式转换为它。implicit class CollectionExtensions[Repr](val self: Repr) extends AnyVal { def toOption[A](implicit ev: Repr => TraversableOnce[A]): Option[Repr] = { val traversable = ev(self) if (traversable.isEmpty) None else Some(self) } }
这两种方法都保留了原始类型:
scala> List(1, 2, 3).toOption
res1: Option[List[Int]] = Some(List(1, 2, 3))
scala> Iterator(1, 2, 3).toOption
res2: Option[Iterator[Int]] = Some(non-empty iterator)
scala> Array.empty[Int].toOption
res3: Option[Array[Int]] = None
scala> Map(1 -> 2).toOption
res4: Option[scala.collection.immutable.Map[Int,Int]] = Some(Map(1 -> 2))
scala> "123".toOption
res5: Option[String] = Some(123)
scala> "".toOption
res6: Option[String] = None
关于scala - 如何为 Scala 中的任何集合创建一个通用的隐式类?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44777011/