【问题标题】:Is Array[String] not a subclass of Seq[String] in Scala?Array[String] 不是 Scala 中 Seq[String] 的子类吗?
【发布时间】:2012-07-16 09:43:50
【问题描述】:

我写了一个方法,它接受 Seq[String] 的所有子类的对象。不幸的是,它不接受 Array[String] 类型的对象。 Array[String] 不是 Seq[String] 的子类吗?

scala> def test[T <: Seq[String]](x: T) = {}
test: [T <: Seq[String]](x: T)Unit

scala> val data = "This is a test string"
data: java.lang.String = This is a test string

scala> test(data.split(" "))
<console>:10: error: inferred type arguments [Array[java.lang.String]] do not conform to method test's type parameter bounds [T <: Seq[String]]
              test(data.split(" "))

【问题讨论】:

    标签: arrays scala scala-collections seq


    【解决方案1】:

    不,Array[String] 转换为常规 JVM 数组,就像您在 Java 中看到的那样:String[]

    您之所以在 Array[String] 上看到您在其他 Scala 的 Seq 集合上看到的所有操作,是因为从 Array[T]ArrayOps[T] 之间存在一个 implicit conversion

    这样做:

    def test[T <% Seq[String]](x: T) = {}
    

    这称为视图绑定。这意味着T 应该是Seq[String] 的子类型,或者应该存在将T 转换为Seq[String] 的范围内的隐式转换。在幕后,编译器实际上给test添加了一个隐式参数,所以这个方法就变成了:

    scala> def test[T <% Seq[String]](x: T) = {}
    test: [T](x: T)(implicit evidence$1: T => Seq[String])Unit
    

    这个implicit evidence$1 是函数,它现在充当方法体内从TSeq[String] 的隐式转换。

    【讨论】:

    • 稍微解释一下视图绑定的工作,这个答案将解释这里发生的所有重要事情。
    • 很有启发性。我对 Scala 还是陌生的,视图边界对我来说是新的。我会进入那个。感谢您的快速回复。
    【解决方案2】:

    源(或API docs)状态,Array 被定义为

    final class Array[T] extends Serializable with Cloneable
    

    也就是说,它不是Seq 的子类型。但是,文档还提到了隐式转换 WrappedArray,后者是 Seq 的子集。

    【讨论】:

      猜你喜欢
      • 2022-08-23
      • 1970-01-01
      • 2020-08-12
      • 1970-01-01
      • 1970-01-01
      • 2020-04-23
      • 2020-08-17
      • 1970-01-01
      • 2016-08-22
      相关资源
      最近更新 更多