Czy parametry konstruktora scala są domyślne dla prywatnego val?

Próbowałem:

class Foo(bar: Int)

Vs:

class Foo(private val bar: Int)

I wydają się zachowywać tak samo, chociaż nigdzie nie mogłem znaleźć stwierdzenia, że (bar: Int) rozszerza się do (private val bar: Int) więc moje pytanie brzmi, czy są to identyczny/podobny?

Na marginesie, próbowałem użyć -Xprint:typer na tych fragmentach kodu i wyprodukuj ten sam kod z wyjątkiem dodatkowej linii w drugiej. Jak przeczytałeś ten dodatkowy tekst?

..
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>();
    ()
  }
}
..
Author: giampaolo, 2013-02-05

2 answers

bar: Int

Jest to zaledwie parametr konstruktora. Jeśli ta zmienna nie jest używana nigdzie poza konstruktorem, pozostaje tam. Nie jest generowane żadne pole. W przeciwnym razie zostanie utworzone pole private val bar i przypisana do niego wartość parametru bar. Nie jest tworzony getter.

private val bar: Int

Taka deklaracja parametru utworzy private val bar pole z prywatnym getterem. To zachowanie jest takie samo jak powyżej, bez względu na to, czy parametr został użyty obok konstruktora (np. w toString() lub nie).

val bar: Int

To samo co wyżej, ale getter podobny do Scali jest publiczny

bar: Int in case classes

Gdy są zaangażowane klasy case, domyślnie każdy parametr ma modyfikator val.

 152
Author: Tomasz Nurkiewicz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-08-17 06:04:40

W pierwszym przypadku, bar jest tylko parametrem konstruktora. Ponieważ głównym konstruktorem jest zawartość samej klasy, jest ona dostępna w niej, ale tylko z tej samej instancji. Jest więc niemal równoznaczne z:

class Foo(private[this] val bar:Int)

Z drugiej strony, w drugim przypadku bar jest normalnym prywatnym polem, więc jest ono dostępne dla tej instancji i innych instancji Foo. Na przykład, to kompiluje fine:

class Foo(private val bar: Int) {
  def otherBar(f: Foo) {
    println(f.bar) // access bar of another foo
  }
}

I biegnie:

scala> val a = new Foo(1)
a: Foo = Foo@7a99d0af

scala> a.otherBar(new Foo(3))
3

Ale to nie:

class Foo(bar: Int) {
  def otherBar(f: Foo) {
    println(f.bar) // error! cannot access bar of another foo
  }
}
 69
Author: gourlaysama,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-02-04 20:19:26