Параметры scala конструктора по умолчанию для private val?
Я пытался:
class Foo(bar: Int)
против
class Foo(private val bar: Int)
и они, похоже, ведут себя одинаково, хотя я не мог найти нигде, говоря, что (bar:
Int)
расширяется до (private val bar: Int)
, так что мой вопрос в том, являются ли эти
идентичный/подобный?
На стороне примечания, я пытался использовать -Xprint:typer
на этих фрагментах кода, и они
производят тот же код, за исключением дополнительной строки во втором. Как мне
прочитайте эту дополнительную строку?
..
class Foo extends scala.AnyRef {
<paramaccessor> private[this] val bar: Int = _;
def <init>(bar: Int): this.Foo = {
Foo.super.<init>();
()
}
}
..
..
class Foo extends scala.AnyRef {
<paramaccessor> private[this] val bar: Int = _;
<stable> <accessor> <paramaccessor> private def bar: Int = Foo.this.bar;
def <init>(bar: Int): this.Foo = {
Foo.super.<init>();
()
}
}
..
Ответы
Ответ 1
bar: Int
Это едва ли параметр конструктора. Если эта переменная не используется нигде, кроме конструктора, она остается там. Поле не генерируется. В противном случае создается поле private val bar
и ему присваивается значение параметра bar
. Создатель не создается.
private val bar: Int
Такое объявление параметра создаст поле private val bar
с частным получателем. Это поведение такое же, как и выше, независимо от того, использовался ли параметр рядом с конструктором (например, в toString()
или нет).
val bar: Int
То же, что и выше, но Scala -пользователь-получатель является общедоступным
bar: Int
в случае классов
При использовании классов case по умолчанию каждый параметр имеет модификатор val
.
Ответ 2
В первом случае bar
является только параметром конструктора. Поскольку основной конструктор является содержимым самого класса, он доступен в нем, но только из этого самого экземпляра. Таким образом, это почти эквивалентно:
class Foo(private[this] val bar:Int)
С другой стороны, во втором случае bar
является обычным частным полем, поэтому он доступен для этого экземпляра и других экземпляров Foo
.
Например, это компилируется отлично:
class Foo(private val bar: Int) {
def otherBar(f: Foo) {
println(f.bar) // access bar of another foo
}
}
И запускается:
scala> val a = new Foo(1)
a: Foo = [email protected]
scala> a.otherBar(new Foo(3))
3
Но это не так:
class Foo(bar: Int) {
def otherBar(f: Foo) {
println(f.bar) // error! cannot access bar of another foo
}
}