2016-12-05 2 views
1

Я замечаю метод, называемый «компаньон» в классе List. Что оно делает? Его определение: «Объект фабричного компаньона, который создает экземпляры класса 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

возможно. Объект, возвращенный со спутника, также может быть использован для создания изменчивых коллекций (Builders), но почему бы мне создать новый список или сборщиков таким образом! вал L5 = l2.newBuilder [Список [строка]] L5: scala.collection.mutable.Builder [Список [строка], Список [Список [строка]]] = ListBuffer() l5 + = Список ("ч ") l5 + = список (" 2 ") println (l5) ListBuffer (Список (h), список (2)) res3: Unit =() –

ответ

1

Это не значит, что вы используете его в обычных условиях. Многие сопутствующие объекты классов коллекции наследуют от GenericCompanion. Все, что наследует от него, должно реализовать newBuilder, которое предоставляет Builder для соответствующего типа коллекции. В свою очередь, этот компаньонный объект этой коллекции наследует методы и empty, которые используются практически повсеместно в стандартной библиотеке коллекций.

Вероятность того, что каждый List (и многие другие коллекции) имеет ссылку на свой собственный спутник, так что его можно использовать для дженериков, особенно с более высокими видами.

Нет родного способа подключения типа со своим спутником, используя только систему типов. Например, если вы хотите получить M[A] <: Traversable[A], у вас нет способа найти его компаньона (в общем, такой общий тип, как это, возможно, даже не один). Чтобы обойти это, мы требуем, чтобы сама коллекция имела ссылку на собственный собеседник (с другими параметрами и ограничениями). Это также избавляет от необходимости иметь множество реализаций apply и empty, скопированных во всех коллекциях.

Смежные вопросы