Подтвердить что ты не робот

Scala Параметры конструктора

В чем разница между частным параметром конструктора var и параметром конструктора без val/var? Являются ли они одинаковыми с точки зрения охвата/видимости?

Пример:

class Person(private var firstName:String, lastName:String)
4b9b3361

Ответ 1

Да, есть два важных отличия. Сначала для простого: параметры конструктора без ключевых слов var или val не являются изменяемыми переменными - их значения не могут быть изменены в теле класса.

Даже если мы ограничимся ключевым словом val, тем не менее, существует разница между параметрами private val и keyword-less. Рассмотрим следующее:

class Person(private val firstName: String, lastName: String)

Если мы посмотрим на скомпилированный класс с javap -v Person, мы увидим, что у него есть только одно поле для firstName. lastName - это просто параметр конструктора, что означает, что он может быть собран в мусор после инициализации класса и т.д.

Компилятор достаточно умен, чтобы знать, когда после инициализации потребуется значение lastName, и в этом случае оно создаст для него поле. Рассмотрим следующую вариацию:

class Person(private val firstName: String, lastName: String) {
  def fullName = firstName + " " + lastName
}

Компилятор может сказать, что позже может понадобиться значение lastName, и если мы снова проверим javap, мы увидим, что класс имеет два поля (обратите внимание, что если бы мы определили fullName как val вместо def, у него будет только одно поле).

Наконец, обратите внимание, что если мы делаем firstName object-private вместо class-private, он работает точно так же, как простой конструктор-конструктор с ключевым словом:

class Person(private[this] val firstName: String, lastName: String)

Это работает даже с var вместо val:

class Person(private[this] var firstName: String, lastName: String)

Оба этих класса не будут иметь полей. Дополнительную информацию об объектно-частном доступе см. В разделе 5.2 спецификации языка.

Ответ 2

в качестве дополнения, если ваш класс является классом case, все параметры конструктора будут автоматически публичными.

Компилятор будет жаловаться на ключевое слово private, если оно существует, и для параметров без val/var, независимо от того, используются они или нет в каких-либо defs, для них будут созданы публичные поля.