Есть ли параметры конструктора 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 109

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
  }
}