首先要区分 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
示例,值
scala> val somethingelse = 2 + 3 * 5 // it's evaluated, eagerly upon definition
somethingelse: Int = 17
示例,变量
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')创建一个不可变标签。每当需要修改可变字段'age'时,尝试都会失败:
scala> personA.age = 44
personA.age: Int = 25
正如预期的那样,'age' 是不可变标签的一部分。正确的处理方法是使用可变变量,就像以下示例中所示:
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
变量的内部状态可以进行更改,但该变量所引用的对象不能被改变。val
不是常量。 - pferrelList
标记为final
,但可以修改其内容。 - jFrenetic