Я б почав з розрізнення, яке існує в 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 (тобто «персонами»). Щоразу, коли «вік» змінного поля потрібно змінювати, така спроба не вдається:
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
ва можна змінити, але об'єкт, на який посилається val, не може. Аval
- не константа.