No Scala, vejo esse recurso como variável privada do objeto. Com meu conhecimento não muito rico em Java, aprendi a fechar tudo (torná-lo privado) e abrir (fornecer acessadores) se necessário. Scala apresenta um modificador de acesso ainda mais restrito. Devo sempre usá-lo por padrão? Ou devo usá-lo apenas em alguns casos específicos em que preciso restringir explicitamente a alteração do valor do campo, mesmo para objetos da mesma classe? Em outras palavras, como devo escolher entre
class Dummy {
private var name = "default name"
}
class Dummy {
private[this] var name = "default name"
}
O segundo é mais rígido e gosto dele, mas devo usá-lo sempre ou apenas se tiver um motivo forte?
EDITADO: Como vejo aqui private[this]
é apenas um subcaso e em vez de this
posso usar outros modificadores: "pacote, classe ou objeto singleton". Então, vou deixar para algum caso especial.
Respostas:
Eu não acho que isso importe muito, já que qualquer mudança afetará apenas uma classe de qualquer maneira. Assim, a razão mais importante para preferir
private
maisprotected
longopublic
não se aplica.Use
private[this]
onde o desempenho realmente importa (já que você obterá acesso direto ao campo em vez de métodos desta forma). Caso contrário, escolha apenas um estilo para que as pessoas não precisem descobrir por que essa propriedade éprivate
e aquela que éprivate[this]
.fonte
private
qualquer maneira, então o impacto deve ser zero ou pelo menos muito pequeno.Há um caso em que
private[this]
é necessário fazer a compilação do código. Isso tem a ver com uma interação de notação de variância e variáveis mutáveis. Considere a seguinte classe (inútil):Portanto, essa classe é projetada para conter um valor opcional, retorná-lo como uma opção e permitir que o usuário faça uma chamada
makeEmpty
para limpar o valor (daí o var). Conforme declarado, isso é inútil, exceto para demonstrar o ponto.Se você tentar compilar este código com em
private
vez de,private[this]
ele falhará com a seguinte mensagem de erro:Este erro ocorre porque o valor é uma variável mutável no tipo covariante T (+ T) que normalmente é um problema, a menos que seja marcado como privado para a instância com
private[this]
. O compilador tem tratamento especial em sua verificação de variância para tratar deste caso especial.Portanto, é esotérico, mas há um caso em que
private[this]
é necessário terminarprivate
.fonte
private var name
é acessível a partir de qualquer método doclass Dummy
(e seu companheiroobject Dummy
).private[this] var name
é acessível a partir de métodos dethis
objeto apenas, não de outros objetos declass Dummy
.fonte
então você pode fazer isso de forma privada sempre que quiser, mas você pode ter algum problema se precisar encaminhá-lo
fonte
private[this]
não é igual aprotected[this]
.protected[this]
permite que instâncias de subclasse acessem o membro.this.y == that.y
usando nem privado nem privado [isto], eu apenas tentei ambosIsso foi testado usando o scala 2.11.5. Considere o código abaixo
ele irá compilar e funcionar como este código java (1.8)
entretanto, se você usar o modificador '[this]', o código abaixo não compilará
Isso ocorre porque no primeiro caso 'x' está acessível no nível da classe, enquanto no segundo caso é mais estrito no nível da instância. Isso significa que 'x' pode ser acessado apenas a partir da instância a que pertence. Portanto, 'this.x' está bem, mas 'other.x' não.
Você pode consultar a seção 13.5 do livro "Programação no Scala: um guia passo a passo abrangente" para obter mais detalhes sobre modificadores de acesso.
fonte
private[this]
significa. Observe a primeira frase.Ao adicionar o escopo ao modificador privado ( private [X] ), ele efetivamente se comporta como um “até” X, onde X designa algum pacote, classe ou objeto singleton envolvente.
Por exemplo, private [bar] , onde bar é um pacote significa que cada instância de cada classe pertencente ao pacote bar pode acessar qualquer membro que o modificador esteja restringindo.
No caso de private [this] , significa que o membro está acessível apenas para cada instância. Isso fica mais claro no seguinte exemplo:
Como você pode ver, o segundo Foo não tem nenhum problema, pois qualquer instância pode acessar o val i privado. No entanto, para o primeiro Foo, há um erro, pois cada instância não pode ver o i de outra instância.
É uma boa prática escrever privado [this], pois impõe uma restrição maior.
fonte
Na maioria das linguagens de programação OOP como java, campos / métodos privados significam que esses campos / métodos privados não são acessíveis fora da classe. No entanto, instâncias / objetos da mesma classe podem ter acesso aos campos privados de objetos usando o operador de atribuição ou por meio do construtor de cópia. No Scala, private [this] é o objeto privado, o que garante que qualquer outro objeto da mesma classe não possa acessar membros privados [this].
Exemplo
1.Sem privado [este]
2. Usando privado [este]
Portanto, private [this] garante que o campo _password só seja acessível com isso.
fonte
Para elaborar o problema de desempenho que Alexey Romanov mencionou, aqui estão alguns de meus palpites. Citações do livro "Programming in Scala: A Comprehensive Step-by-Step Guide, 2nd Edition" Seção 18.2:
Para testá-lo, este código causará um erro de compilação:
Scala reclama
error: ambiguous reference to overloaded definition
. Adicionar a palavra-chave overridedata_=
não ajudará a provar que o método é gerado pelo compilador. Adicionarprivate
palavra-chave à variáveldata
ainda causará este erro de compilação. No entanto, o código a seguir é compilado corretamente:Portanto, acho
private[this]
que impedirá que o scala gere métodos getter e setter. Portanto, acessar essa variável irá economizar a sobrecarga de chamar os métodos getter e setter.fonte
É melhor usar
private[this]
se você planeja sincronizar a variável.Aqui está um bom exemplo do guia de estilo scala da equipe Spark :
fonte