Tutaj wypełniam dwie listy, na których każda jest albo zmienna, albo niezmienna:
var mutableList = scala.collection.mutable.MutableList[String]()
//> mutableList : scala.collection.mutable.MutableList[String] = MutableList()
//|
for (a <- 1 to 100) {
mutableList += a.toString
}
println(mutableList.size); //> 100
val immutableList = List[String]() //> immutableList : List[String] = List()
for (a <- 1 to 100) {
immutableList :+ a.toString
}
println(immutableList.size); //> 0
Kiedy drukuję rozmiar niezmiennej listy, towynik wynosi 0. Jest tak, ponieważ w pętli for tworzone jest nowe odwołanie, które nie wskazuje na immutableList? Czy istnieje funkcjonalny odpowiednik wypełniania niezmiennej listy z pętli wewnętrznej?
Odpowiedzi:
3 dla odpowiedzi № 1Jak odpowiedział Gabor w komentarzu, chcesz użyć fold
, a nawet kontynuować korzystanie z for i yield
. Nie wyjaśnił, dlaczego dostajesz rozmiar 0. Powód jest taki immutableList :+ a.toString
zwraca za każdym razem nową listę, której nie używasz. immutableList
jest dokładnie to, niezmienne.
Pamiętaj, że wszystko w Scali jest wyrażeniem i dlatego coś zwraca. Możesz więc zmienić swój zwyczajny for
(który działa jak forEach
) w zrozumieniu poprzez dodanie yield
jak poniżej
val immutableList = for (a <- 1 to 100) yield a.toString
To zapada w coś takiego:
(1 to 100).map(_.toString)
1 dla odpowiedzi nr 2
Dla kompletności, metoda tabulate
pozwala na tworzenie i wypełnianie niezmiennego List
, na przykład w następujący sposób,
List.tabulate(100)(a => a.toString)
lub równoważnie
List.tabulate(100)(_.toString)