Scala - why does :: not change a List? [duplicate]

2019-09-22 08:20发布

问题:

This question already has an answer here:

  • Immutable Lists in Scala 5 answers

I have just written this code for some fun and I have a question why it isn't working out?

  val list = List[Int]()

  while (list.length < 20) {  
    Random.nextInt(100) :: list
  }

  println(list)
}

Seems like nothing is written to the list, but why is that so? Do I have to make it mutable? And why is here the :: operator not working properly?

回答1:

Because x :: xs returns a new list, where the first element is x, followed by xs.

So, to make your code work, make list a var and re-assign it inside the loop:

var list = List[Int]()

while(list.length < 20)
  list = Random.nextInt(100) :: list

However, the idiomatic way of doing this in Scala is to not use mutations at all (local mutable state is fine sometimes though). "While" loops can usually be replaced with a recursive function:

def go(xs: List[Int]) =
  if (xs.length >= 20) xs
  else go(Random.nextInt(100) :: xs)

go(List())

This particular scenario can also be solved using List.fill instead

val list = List.fill(20)(Random.nextInt(100))