Os parâmetros do construtor scala assumem como padrão o valor privado?

128

Eu tenho tentado:

class Foo(bar: Int)

vs:

class Foo(private val bar: Int)

e eles parecem se comportar da mesma forma, embora eu não tenha encontrado nenhum lugar que diga que se (bar: Int)expanda, (private val bar: Int)então minha pergunta é: são idênticos / similares?

Em uma nota lateral, eu tenho tentado usar -Xprint:typeressas partes de código e elas produzem o mesmo código, exceto por uma linha extra no segundo. Como leio essa linha extra?

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

Respostas:

177

bar: Int

Este é apenas um parâmetro construtor. Se essa variável não for usada em nenhum lugar, exceto no construtor, ela permanecerá lá. Nenhum campo é gerado. Caso contrário, o private val barcampo é criado e o valor do barparâmetro é atribuído a ele. Nenhum getter é criado.

private val bar: Int

Essa declaração de parâmetro criará um private val barcampo com getter privado. Esse comportamento é o mesmo que acima, não importa se o parâmetro foi usado ao lado do construtor (por exemplo, dentro toString()ou não).

val bar: Int

O mesmo que o anterior, mas o getter semelhante ao Scala é público

bar: Int nas classes de caso

Quando as classes de casos estão envolvidas, por padrão, cada parâmetro possui valmodificador.

Tomasz Nurkiewicz
fonte
15
Nas classes de caso, todos os parâmetros se tornarão "públicos" val.
Drexin
6
Puxa, eu uso óculos de vez em quando, mas isso é demais.
Om-nom-nom
1
@ om-nom-nom: desculpe, eu não entendi. Devo melhorar a formatação / estrutura para torná-lo mais legível?
Tomasz Nurkiewicz
1
@TomaszNurkiewicz: varestá disponível e significativo a renda parâmetros do construtor em propriedades (mutável) classe tanto em não casee caseclasses.
Randall Schulz
8
No livro 'Scala for the Imppatient', escrito bar: Intparaprivate[this] val bar: Int
MyTitle
98

No primeiro caso, baré apenas um parâmetro construtor. Como o construtor principal é o conteúdo da própria classe, ele é acessível, mas somente a partir desta instância. Portanto, é quase equivalente a:

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

Por outro lado, no segundo caso, baré um campo privado normal , portanto, é acessível a essa instância e a outras instâncias de Foo. Por exemplo, isso compila bem:

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

Mas isso não acontece:

class Foo(bar: Int) {
  def otherBar(f: Foo) {
    println(f.bar) // error! cannot access bar of another foo
  }
}
Gourlaysama
fonte
9
esta é uma resposta melhor que a aceita; destaca a diferença entre bare bar: Inte private val ....
Hraban