2016-12-27 13 views
10

Jestem trochę zmieszany z powodu dostępnych operatorów +: i ::.Listy w Scali - plus dwukropek vs podwójny dwukropek (+: vs: :)

Wygląda na to, że oba dają takie same wyniki.

scala> List(1,2,3) 
res0: List[Int] = List(1, 2, 3) 

scala> 0 +: res0 
res1: List[Int] = List(0, 1, 2, 3) 

scala> 0 :: res0 
res2: List[Int] = List(0, 1, 2, 3) 

Na moje oko nowicjusza kodu źródłowego dla obu metod wygląda podobnie (metoda plus dwukropek ma dodatkowy warunek na rodzajowych z wykorzystaniem fabrykach producenta).

Którą z tych metod należy zastosować i kiedy?

+0

Dobre miejsce na rozpoczęcie: wypróbuj to samo z 'Seq' zamiast' List' ... –

Odpowiedz

11

+: współpracuje z dowolną kolekcją, a :: jest specyficzną implementacją dla List. Jeśli przyjrzysz się dokładnie source dla +:, zauważysz, że w rzeczywistości wywołuje ::, gdy oczekiwany typ zwrotu to List. Dzieje się tak dlatego, że :: jest bardziej efektywnie zaimplementowany w przypadku List: po prostu łączy nową głowicę z istniejącą listą i zwraca wynik, który jest operacją o stałym czasie, w przeciwieństwie do liniowego kopiowania całej kolekcji w ogólnym przypadku: +: .

+: Z drugiej strony, zajmuje CanBuildFrom, więc można zrobić ozdobna (aczkolwiek, nie patrząc jak ładnie w tym przypadku) takie rzeczy jak:

val foo: Array[String] = List("foo").+:("bar")(breakOut) 

(To całkiem bezużyteczny w tym konkretnym przypadku, jak ty może zacząć od wymaganego typu, ale pomysł polega na tym, że możesz dodać element do kolekcji i zmienić jego typ w jednym "przejściu", unikając dodatkowej kopii).

Powiązane problemy