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>();
()
}
}
..
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
.
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
}
}
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