Eu começaria pela distinção que existe em Scala entre def , val e var .
def - define um rótulo imutável para o conteúdo do lado direito que é avaliado preguiçosamente - avalie pelo nome.
val - define um rótulo imutável para o conteúdo do lado direito que é avidamente / imediatamente avaliado - avaliado por valor.
var - define uma variável mutável , inicialmente definida como o conteúdo avaliado do lado direito.
Exemplo, def
scala> def something = 2 + 3 * 4
something: Int
scala> something // now it's evaluated, lazily upon usage
res30: Int = 14
Exemplo, val
scala> val somethingelse = 2 + 3 * 5 // it's evaluated, eagerly upon definition
somethingelse: Int = 17
Exemplo, var
scala> var aVariable = 2 * 3
aVariable: Int = 6
scala> aVariable = 5
aVariable: Int = 5
De acordo com o acima, as etiquetas def e val não podem ser reatribuídas e, em caso de tentativa, será gerado um erro como o abaixo:
scala> something = 5 * 6
<console>:8: error: value something_= is not a member of object $iw
something = 5 * 6
^
Quando a classe é definida como:
scala> class Person(val name: String, var age: Int)
defined class Person
e instanciado com:
scala> def personA = new Person("Tim", 25)
personA: Person
um rótulo imutável é criado para essa instância específica de Person (ou seja, 'personA'). Sempre que o campo mutável 'idade' precisar ser modificado, essa tentativa falha:
scala> personA.age = 44
personA.age: Int = 25
como esperado, 'idade' faz parte de um rótulo não mutável. A maneira correta de trabalhar nisso consiste em usar uma variável mutável, como no exemplo a seguir:
scala> var personB = new Person("Matt", 36)
personB: Person = Person@59cd11fe
scala> personB.age = 44
personB.age: Int = 44 // value re-assigned, as expected
Como claro, a partir da referência da variável mutável (ou seja, 'personB'), é possível modificar o campo mutável da classe 'age'.
Eu ainda enfatizaria o fato de que tudo deriva da diferença acima mencionada, que deve estar clara em mente para qualquer programador Scala.
val
pode ser alterado, mas o objeto referido por uma val não pode. Aval
não é uma constante.