scala - 如何为 Scala 中的任何集合创建一个通用的隐式类?

标签 scala generics collections implicit-conversion

我想写一个方法,如果集合为空则返回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。这种方法还支持 ArrayString,因为它们根本不扩展 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/

相关文章:

scala - 如何将 List[List[Long]] 转换为 List[List[Int]]?

scala - 进程间通信的静态类型参与者模型有什么不可行的地方吗?

python - 在 Scala 中将列表或映射作为函数参数展开

java - 如何在akka actor中设置构造字段或配置加载?

typescript - 类型映射时通用属性的问题

java - Java中的HashMap碰撞安全吗

java - 如何在 spring-boot 中为泛型类提供类类型?

java - 文本文件中的通用二叉树

java - 什么时候 ArrayList 比 Java 中的数组更可取?

java - 如何在java中对ArrayList的ArrayList进行排序?