2012-07-17 40 views
9

我寫了一個接受Seq [String]的所有子類的對象的方法。不幸的是,它不會接受Array [String]類型的對象。 Array [String]不是Seq [String]的子類嗎?數組[String]不是Scala中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(" ")) 

回答

10

沒有,Array[String]轉化爲常規的JVM陣列,就像您在Java中看到的:String[]

爲什麼你看到所有的操作上Array[String],你看到其他的Scala Seq藏品的原因是,有一個implicit conversionArray[T]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是現在用作從TSeq[String]的方法的主體內的隱式轉換的功能。

+2

解釋了視圖的工作一點點,這個答案將解釋所有重要的事情在這裏。 – sschaef 2012-07-17 13:09:03

+0

非常有啓發性。我對Scala仍然陌生,對我來說,視圖範圍是新的。我會進入。感謝您的快速回復。 – 2012-07-17 13:19:01

3

的源(或API docs)狀態,即Array被定義爲

final class Array[T] extends Serializable with Cloneable 

即,它不是Seq子類型。但是,文檔還提到了隱式轉換WrappedArray,其中後者是Seq的子集。

相關問題