我编写了一个接受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(" "))
答案 0 :(得分:11)
不,Array[String]
转换为常规JVM数组,就像您在Java中看到的那样:String[]
。
您在其他Scala Array[String]
集合中看到Seq
上的所有操作的原因是Array[T]
到implicit conversion ArrayOps[T]
}。
这样做:
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
是现在充当方法正文中从T
到Seq[String]
的隐式转换的函数。
答案 1 :(得分:3)
源(或API docs)状态,Array
定义为
final class Array[T] extends Serializable with Cloneable
也就是说,它不是Seq
的子类型。但是,文档还提到了隐式转换WrappedArray
,其中后者是Seq
的子集。