2016-12-05 52 views
1

我注意到List類中名爲'companion'的方法。它有什麼作用?它的定義是'構建類List實例的工廠伴侶對象'。列表中的伴侶方法

看來我可以使用l.companion(11,12,13)方法創建列表的新實例,但爲什麼我會這樣做而不是使用List(11,12,13)?

val l = List[Int](1,2,3,4,1) 
l: List[Int] = List(1, 2, 3, 4, 1) 

val l2 = l.companion 
l2: scala.collection.generic.GenericCompanion[List] = [email protected] 

//I can create new instances of a List using l2 but why would I do it this way? 
val l3 = l2(100,11,123) 

l3.foreach(println _) 
100 
11 
123 
res0: Unit =() 

從伴侶返回的對象也可用於創建可變集合(構建器)。但爲什麼我會用這種方式創建集合!

//create a Builder (a mutable collection) whose elements would be list of strings 
val l5 = l2.newBuilder[List[String]] 
l5: scala.collection.mutable.Builder[List[String],List[List[String]]] = ListBuffer() 

l5+=List("h") 
l5+=List("2") 

println(l5) 
ListBuffer(List(h), List(2)) 
res3: Unit =() 
+0

可能只是爲了某些代碼重用庫集合 –

+0

也許。從伴侶返回的對象也可用於創建可變集合(構建器),但爲什麼我會以這種方式創建新列表或構建器! val l5 = l2.newBuilder [List [String]] l5:scala.collection.mutable.Builder [List [String],List [List [String]]] = ListBuffer() l5 + = List(「h 「) lll + =列表(」2「) println(l5) ListBuffer(List(h),List(2)) res3:Unit = –

回答

1

在一般情況下,這並不是真正的意思。集合類的許多伴隨對象從GenericCompanion繼承。任何從它繼承的東西都必須實現newBuilder,它爲關聯的集合類型提供Builder。反過來,該集合的伴隨對象繼承了applyempty方法,這些方法幾乎在標準集合庫中的任何地方都使用。

每個List(和許多其他集合)都有一個引用它自己的伴侶的(可能)原因是它可以用於泛型,特別是對於更高類型的泛型。

只有使用類型系統才能將類型與其伴侶連接起來。例如,如果你想要一些M[A] <: Traversable[A],你沒有辦法找到它的夥伴(通常,這樣的泛型可能甚至沒有)。爲了解決這個問題,我們要求集合本身有一個引用它自己的夥伴(以及其他類型參數和約束)。這還節省了在所有集合中複製applyempty的多個實現的需要。