我只是想弄清楚像 List 这样不可变的东西是如何工作的,以及如何向其中添加东西?
你不能。毕竟,这就是不可变的意思。如果拉丁语不是你的一杯茶,immutable 的英文翻译是 unchangeable。现在应该清楚了,为什么你不能改变一些不可改变的。
我很抱歉问了这么愚蠢的问题,但是为什么我的列表打印出来时总是空的?
您创建了一个空列表,并且您永远不会更改它(因为它无法无论如何都无法更改)。所以,当然是空的。
您可以做什么,但是,创建一个 new 列表,它几乎与 old 列表完全一样,除了新的前面的项目。这就是你在这里所做的:
input :: list
但是,您不会将这个新列表分配到任何地方,也不会返回它,而是完全忽略它。
如果您想以任何方式实际使用您的列表,您需要以某种方式记住它。最明显的解决方案是将其分配给一个变量:
var end = false
var list: List[String] = List() // note: `var` instead of `val`
while (!end) {
val input = scala.io.StdIn.readLine("input:")
if (input == "stop" ) end = true
else list = input :: list // note: assign to `list`
}
println(list)
但是,这不是很地道。毕竟,我们现在已经获取了一个 immutable 列表并将其分配给一个 mutable 变量…… IOW,我们刚刚移动了可变性。
相反,我们可以使用递归解决方案:
def buildListFromInput(list: List[String] = List()): List[String] = {
val input = scala.io.StdIn.readLine("input:")
if (input == "stop") list else buildListFromInput(input :: list)
}
println(buildListFromInput())
这个方案不仅是递归的,递归调用也是在tail位置(IOW,方法是tail-recursive),也就是说它会只是与while 循环一样高效(实际上,它将被编译为while 循环,或者更准确地说,编译为GOTO)。 Scala 语言规范保证 Scala 的所有实现必须消除直接尾递归。