Я бы начал с различия, которое существует в 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
, создается неизменная метка дляэтот конкретный экземпляр лица (то есть'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.