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.