我正在阅读Scala Creator编写的Scala编程书,我对Set的例子有点困惑.
这里是不可变集:
var jetSet = Set("Boeing", "Airbus")
jetSet += "Lear"
println(jetSet.contains("Cessna"))
Run Code Online (Sandbox Code Playgroud)
这有什么意义?
该集是不可变的,但变量jetSet是可变的.1)所以每次我用+ =添加到集合中它会创建一个新集合?那么变量指向内存中的新集合?
2)不应该是:
val jetSet = set("cow","sheep","duck") ?为什么它必须是var?是否有理由将var用于不可变集合?
Kip*_*ros 16
不可变数据结构(在本例中为Set)的优点是它们是持久的.例如:
var jetSet1 = Set("Boeing", "Airbus")
val jetSet2 = jetSet1 // ... imagine jetSet2 is somewhere else in the program
jetSet1 += "Lear"
assert(!jetSet2.contains("Lear"))
Run Code Online (Sandbox Code Playgroud)
这些Set对象的不变性使得更容易推理程序,因为对jetSet1变量的更新在代码的其他部分(在这种情况下,无论在何处jetSet2使用)都没有副作用.虽然从这个例子中不清楚,但有时候在可变var引用中存储不可变值是很方便的.最常见的是,var意志范围有限(例如,功能的本地范围).
不可变数据结构通常具有非常高效的巧妙实现.不幸的是,Scala集合API没有关于性能的详细记录,但我预计大多数操作大致为O(log N)时间.例如,给定一个大的不可变集合s,应该能够有效地构造s + x一个带有额外元素的新集合.当然,s也保留了不变性保证.在内部,s并且s+x将使用某种树数据结构的与共享组件来存储.
您的问题的标题表明您也在寻找有关使用val或的建议var.经验法则是val随时随地使用.如果a var是必要的,那么尽量尽量限制变量的范围.
var允许您重新分配给变量,将其视为Java中的常规变量声明.但是在上面的例子中,即使你重新分配给同一个变量,它总是一个不同的集合,因为你使用的是一个不可变的变量.
该示例的要点是表明即使您尝试"修改"不可变集合,修改也会创建一个新集合,而不是触及原始集合.如果作者使用了val(final在Java中),他将不得不在范围中引入一个变量来保存新的不可变集.我认为var可能用于保持示例简单.