wake-up-neo.com

Haben scala Konstruktorparameter den Standardwert private val?

Ich habe es versucht:

class Foo(bar: Int)

vs:

class Foo(private val bar: Int)

und sie scheinen sich gleich zu verhalten, obwohl ich nirgends finden konnte, dass (bar: Int) erweitert auf (private val bar: Int) meine frage ist also, sind diese identisch/ähnlich?

Nebenbei habe ich versucht, -Xprint:typer auf diesen Codeteilen und sie produzieren den gleichen Code mit Ausnahme einer zusätzlichen Zeile in der zweiten. Wie lese ich diese zusätzliche Zeile?

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

bar: Int

Dies ist kaum ein Konstruktorparameter. Wenn diese Variable nur im Konstruktor verwendet wird, bleibt sie dort. Es wird kein Feld generiert. Andernfalls wird das Feld private val bar Erstellt und der Wert des Parameters bar zugewiesen. Es wird kein Getter erstellt.

private val bar: Int

Eine solche Parameterdeklaration erzeugt ein private val bar - Feld mit einem privaten Getter. Dieses Verhalten ist das gleiche wie oben, unabhängig davon, ob der Parameter neben dem Konstruktor verwendet wurde (z. B. in toString() oder nicht).

val bar: Int

Wie oben, aber der Scala-ähnliche Getter ist öffentlich

bar: Int In case Klassen

Wenn Fallklassen beteiligt sind, hat jeder Parameter standardmäßig den Modifizierer val.

167

Im ersten Fall ist bar nur ein Konstruktorparameter. Da der Hauptkonstruktor der Inhalt der Klasse selbst ist, kann auf ihn nur von dieser Instanz aus zugegriffen werden. Es ist also fast gleichbedeutend mit:

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

Andererseits ist bar im zweiten Fall ein normales privates Feld, so dass auf dieses Feld zugegriffen werden kann nd andere Instanzen von Foo. Zum Beispiel kompiliert dies gut:

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

Und läuft:

scala> val a = new Foo(1)
a: Foo = [email protected]

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

Das tut es aber nicht:

class Foo(bar: Int) {
  def otherBar(f: Foo) {
    println(f.bar) // error! cannot access bar of another foo
  }
}
88
gourlaysama