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

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.


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
  }
}

9
esta é uma resposta melhor que a aceita; destaca a diferença entre bare bar: Inte private val ....
— Hraban
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.