List Scala中的不可变列表
我只是想弄清楚像列表这样不可变的东西是如何工作的,以及我如何向其中添加东西 我很抱歉问了这么愚蠢的问题,但为什么在打印时我的列表总是空的List Scala中的不可变列表,list,scala,add,immutability,List,Scala,Add,Immutability,我只是想弄清楚像列表这样不可变的东西是如何工作的,以及我如何向其中添加东西 我很抱歉问了这么愚蠢的问题,但为什么在打印时我的列表总是空的 var end = false val list = List() while (!end) { val input = scala.io.StdIn.readLine("input:") if (input == "stop" ) end = true else input :: list } println(list) } 很抱歉给您带来
var end = false
val list = List()
while (!end) {
val input = scala.io.StdIn.readLine("input:")
if (input == "stop" ) end = true
else input :: list
}
println(list)
}
很抱歉给您带来不便,还有这个愚蠢的问题 原因是什么
println(list)
只打印出一个空列表是因为位
input :: list
实际上并没有改变列表本身。在本例中,它只是临时创建一个包含前面输入的列表
试一试
或
你会明白我的意思 原因是什么
println(list)
只打印出一个空列表是因为位
input :: list
实际上并没有改变列表本身。在本例中,它只是临时创建一个包含前面输入的列表
试一试
或
你会明白我的意思 scala列表中的是不可变的 那么我如何才能将项目添加到列表中? 将项目添加到列表时,新的
列表
实例将以一个项目作为其头部,其尾部现在包含上一个列表
如果在内部有一个名为intList
的“1,2,3”列表,则表示为
列表(3,列表(2,列表(1,无)))
如果将元素4
添加到此intList
列表(4,intList)
让我们调用此newList
注意intList
仍然包含List(3,List(2,List(1,Nil))
如果希望intList
引用newList
,则必须执行以下操作
intList = intList.add(4)
如何修复我的代码 将列表从
val
更改为var
。然后,您可以将结果列表分配给List
变量
list = input :: list
来源:Scala列表中名为的Scala在线课程是不可变的 那么我如何才能将项目添加到列表中? 将项目添加到列表时,新的
列表
实例将以一个项目作为其头部,其尾部现在包含上一个列表
如果在内部有一个名为intList
的“1,2,3”列表,则表示为
列表(3,列表(2,列表(1,无)))
如果将元素4
添加到此intList
列表(4,intList)
让我们调用此newList
注意intList
仍然包含List(3,List(2,List(1,Nil))
如果希望intList
引用newList
,则必须执行以下操作
intList = intList.add(4)
如何修复我的代码 将列表从
val
更改为var
。然后,您可以将结果列表分配给List
变量
list = input :: list
来源:有关Scala的在线课程尝试以更实用的方式重写代码。不可变数据结构上的每个操作都会返回带有更改的新实例。所以
::
操作员在前面用输入创建新列表。您可能希望尝试将此代码重写为尾部递归函数,如下所示
@tailrec
def scanInput(continue: Boolean,acc: List[String]): List[String] = {
val input = scala.io.StdIn.readLine("input:")
if(!continue) acc
else scanInput(input != "stop", input :: acc)
}
上面的代码没有变化状态,它更适合Scala函数风格。尝试以更为函数化的方式重写代码。不可变数据结构上的每个操作都会返回带有更改的新实例。所以::
操作员在前面用输入创建新列表。您可能希望尝试将此代码重写为尾部递归函数,如下所示
@tailrec
def scanInput(continue: Boolean,acc: List[String]): List[String] = {
val input = scala.io.StdIn.readLine("input:")
if(!continue) acc
else scanInput(input != "stop", input :: acc)
}
上面的代码没有变化状态,它更适合Scala函数风格
我只是想弄清楚像列表这样不可变的东西是如何工作的,以及我如何向其中添加东西
你不能。毕竟,这就是不变的含义。如果你不喜欢拉丁语,那么“不变”的英文翻译是不变的。现在应该清楚了,为什么你不能改变一些不可改变的东西
我很抱歉问了这么愚蠢的问题,但为什么在打印时我的列表总是空的
var end = false
val list = List()
while (!end) {
val input = scala.io.StdIn.readLine("input:")
if (input == "stop" ) end = true
else input :: list
}
println(list)
}
您创建了一个空列表,并且从未更改过它(因为它无论如何都无法更改)。所以,它当然是空的
但是,您可以做的是创建一个与旧列表几乎完全相同的新列表,只是在前面添加了一个新项目。这就是你在这里所做的:
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)
然而,这不是很地道。毕竟,我们现在已经获得了一个不可变列表,并将其分配给了一个可变变量……瞧,我们刚刚移动了可变性
相反,我们可以使用递归解决方案:
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())
此解决方案不仅是递归的,递归调用也处于尾部位置(注意,该方法是尾部递归的),这意味着它将与while
循环一样有效(事实上,它将编译成while
循环,或者更准确地说,编译成GOTO
)。Scala语言规范保证Scala的所有实现都必须消除直尾递归
我只是想弄清楚像列表这样不可变的东西是如何工作的,以及我如何向其中添加东西
你不能。毕竟,这就是不变的含义。如果你不喜欢拉丁语,那么“不变”的英文翻译是不变的。现在应该清楚了,为什么你不能改变一些不可改变的东西
我很抱歉问了这么愚蠢的问题,但为什么在打印时我的列表总是空的
var end = false
val list = List()
while (!end) {
val input = scala.io.StdIn.readLine("input:")
if (input == "stop" ) end = true
else input :: list
}
println(list)
}
您创建了一个空列表,并且从未更改过它(因为它无论如何都无法更改)。所以,它当然是空的
但是,您可以做的是创建一个与旧列表几乎完全相同的新列表,只是在前面添加了一个新项目。这就是你在这里所做的:
input :: list
但是,您不会将此新列表分配到任何位置