我将从Scala在def,val和var之间的区别开始。
def-定义右侧内容的不可变标签,该标签延迟评估 -按名称评估。
val-为右侧内容定义一个不变的标签,该标签被急切/立即评估 -通过值评估。
var-定义一个可变变量,最初设置为评估后的右侧内容。
例子,def
scala> def something = 2 + 3 * 4
something: Int
scala> something // now it's evaluated, lazily upon usage
res30: Int = 14
例子val
scala> val somethingelse = 2 + 3 * 5 // it's evaluated, eagerly upon definition
somethingelse: Int = 17
例如,var
scala> var aVariable = 2 * 3
aVariable: Int = 6
scala> aVariable = 5
aVariable: Int = 5
根据以上所述,无法重新分配def和val中的标签,并且在进行任何尝试的情况下都会引发如下错误:
scala> something = 5 * 6
<console>:8: error: value something_= is not a member of object $iw
something = 5 * 6
^
当类定义如下:
scala> class Person(val name: String, var age: Int)
defined class Person
然后用:
scala> def personA = new Person("Tim", 25)
personA: Person
将为该特定的Person实例(即“ personA”)创建一个不变标签。每当需要修改可变字段“年龄”时,这种尝试都会失败:
scala> personA.age = 44
personA.age: Int = 25
正如预期的那样,“年龄”是非可变标签的一部分。解决此问题的正确方法包括使用可变变量,如以下示例所示:
scala> var personB = new Person("Matt", 36)
personB: Person = Person@59cd11fe
scala> personB.age = 44
personB.age: Int = 44 // value re-assigned, as expected
很明显,从可变变量引用(即“ personB”)可以修改类的可变字段“ age”。
我仍然要强调一个事实,即一切都来自上述差异,任何Scala程序员都必须清楚这一点。
val
可以更改a的内部状态,但不能更改val引用的对象。Aval
不是常数。