Есть ли параметры конструктора scala по умолчанию для private val?
Я:
class Foo(bar: Int)
vs:
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>();
()
}
}
..
2 ответа:
bar: Int
это едва ли параметр конструктора. Если эта переменная не используется нигде, кроме конструктора, она остается там. Поле не генерируется. В противном случае
private val bar
поле создается и значениеbar
ему присвоен параметр. Геттер не создается.
private val bar: Int
такое объявление параметра создаст
private val bar
поле с частным добытчиком. Это поведение такое же, как и выше, независимо от того, был ли параметр использован рядом с конструктор (например,toString()
или нет).
val bar: Int
то же самое, что и выше, но Scala-подобный геттер является публичным
bar: Int
в case-классыкогда задействованы классы case, по умолчанию каждый параметр имеет
val
модификатор.
в первом случае
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 = Foo@7a99d0af 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 } }