I parametri del costruttore scala sono impostati su private val?


128

Ci ho provato:

class Foo(bar: Int)

vs:

class Foo(private val bar: Int)

e sembrano comportarsi allo stesso modo anche se non sono riuscito a trovare da nessuna parte dire che si (bar: Int)espande (private val bar: Int)così la mia domanda è: sono identici / simili?

In una nota a margine, ho cercato di utilizzare -Xprint:typerquesti pezzi di codice e producono lo stesso codice tranne una riga aggiuntiva nella seconda. Come posso leggere quella riga aggiuntiva?

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

Risposte:


177

bar: Int

Questo è a malapena un parametro del costruttore. Se questa variabile non viene utilizzata da nessuna parte tranne il costruttore, rimane lì. Nessun campo generato. Altrimenti private val barviene creato il campo e barviene assegnato il valore del parametro. Non viene creato alcun getter.

private val bar: Int

Tale dichiarazione di parametro creerà un private val barcampo con getter privato. Questo comportamento è identico a quello precedente, indipendentemente dal fatto che il parametro sia stato utilizzato accanto al costruttore (ad esempio, dentro toString()o no).

val bar: Int

Come sopra ma il getter alla Scala è pubblico

bar: Int in caso di classi

Quando sono coinvolte classi di casi, per impostazione predefinita ogni parametro ha un valmodificatore.


15
Nel caso in cui tutte le classi diventino "pubbliche" val.
— Drexin,

6
Accidenti, di tanto in tanto indosso gli occhiali, ma questo è troppo.
— om-nom-nom,

1
@ om-nom-nom: scusa, non capisco. Dovrei migliorare la formattazione / struttura per renderla più leggibile?
— Tomasz Nurkiewicz,

1
@TomaszNurkiewicz: varè disponibile e significativo per rendere i parametri del costruttore in proprietà di classe (mutabili) sia in non caseche in caseclassi.
— Randall Schulz,

8
Nel libro 'Scala for the Impatient' scritto che è stato bar: Intcompilato perprivate[this] val bar: Int
— MyTitle il

98

Nel primo caso, barè solo un parametro del costruttore. Poiché il costruttore principale è il contenuto della classe stessa, è accessibile in essa, ma solo da questo esempio. Quindi è quasi equivalente a:

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

D'altra parte, nel secondo caso barè un normale campo privato, quindi è accessibile a questa istanza e ad altre istanze di Foo. Ad esempio, questo compila bene:

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

E corre:

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

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

Ma questo non:

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

9
questa è una risposta migliore di quella accettata; evidenzia la differenza tra nudo bar: Inte private val ....
— hraban,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.