Я бы начал с различия, которое существует в Scala между def , val и var .
def - определяет неизменяемый ярлык для содержимого правой стороны, которое лениво оценивается - оценивается по имени.
val - определяет неизменяемую метку для правого содержимого, которое охотно / немедленно оценивается - оценивается по значению.
var - определяет изменяемую переменную , изначально установленную на оцениваемое содержимое правой стороны.
Пример, определение
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, не может. Аval
не является константой.