Dans Scala, je vois une telle fonctionnalité comme une variable objet-privé. De mon arrière-plan Java pas très riche, j'ai appris à tout fermer (le rendre privé) et à ouvrir (fournir des accesseurs) si nécessaire. Scala introduit un modificateur d'accès encore plus strict. Dois-je toujours l'utiliser par défaut? Ou devrais-je l'utiliser uniquement dans certains cas spécifiques où j'ai besoin de restreindre explicitement la modification de la valeur du champ même pour les objets de la même classe? En d'autres termes, comment choisir entre
class Dummy {
private var name = "default name"
}
class Dummy {
private[this] var name = "default name"
}
La seconde est plus stricte et je l'aime bien mais dois-je toujours l'utiliser ou seulement si j'ai une bonne raison?
EDITED: Comme je le vois, voici private[this]
juste un sous-cas et au lieu de this
je peux utiliser d'autres modificateurs: "package, classe ou objet singleton". Je vais donc laisser cela pour un cas particulier.
Réponses:
Je ne pense pas que cela compte trop, car tout changement ne touchera qu'une seule classe de toute façon. Ainsi , la raison la plus importante à préférer
private
plusprotected
surpublic
ne sont pas applicables.Utilisez
private[this]
là où les performances comptent vraiment (puisque vous aurez un accès direct au champ au lieu des méthodes de cette façon). Sinon, choisissez un style pour que les gens n'aient pas besoin de comprendre pourquoi cette propriété estprivate
et celle- làprivate[this]
.la source
private
, donc l'impact devrait être nul ou au moins très très petit.Il y a un cas où il
private[this]
est nécessaire de faire compiler le code. Cela a à voir avec une interaction de la notation de la variance et des variables mutables. Considérez la classe suivante (inutile):Cette classe est donc conçue pour contenir une valeur facultative, la renvoyer en option et permettre à l'utilisateur d'appeler
makeEmpty
pour effacer la valeur (d'où la variable var). Comme indiqué, cela est inutile sauf pour démontrer le point.Si vous essayez de compiler ce code avec
private
au lieu deprivate[this]
cela, le message d'erreur suivant échouera:Cette erreur se produit car value est une variable mutable sur le type de covariant T (+ T), ce qui pose normalement un problème à moins d'être marqué comme privé pour l'instance avec
private[this]
. Le compilateur a une gestion spéciale dans sa vérification de variance pour gérer ce cas particulier.C'est donc ésotérique mais il y a un cas où il
private[this]
faut plusprivate
.la source
private var name
est accessible depuis n'importe quelle méthode duclass Dummy
(et de son compagnonobject Dummy
).private[this] var name
est accessible à partir des méthodes d'this
objet uniquement, pas à partir d'autres objets declass Dummy
.la source
vous pouvez donc le faire en privé à chaque fois que vous le souhaitez, mais vous pouvez avoir un problème si vous avez besoin de le référer
la source
private[this]
n'est pas égal àprotected[this]
.protected[this]
permet aux instances de sous-classe d'accéder au membre.this.y == that.y
utiliser ni privé ni privé [ceci], j'ai juste essayé les deuxCeci a été testé en utilisant scala 2.11.5. Considérez le code ci-dessous
il compilera et fonctionnera comme ce code java (1.8)
cependant si vous utilisez le modificateur '[this]' le code ci-dessous ne compilera pas
En effet, dans le premier cas, «x» est accessible au niveau de la classe, alors que dans le second cas, il est plus strict au niveau de l'instance. Cela signifie que «x» n'est accessible qu'à partir de l'instance à laquelle il appartient. Donc 'this.x' est bien mais 'other.x' ne l'est pas.
Vous pouvez vous référer à la section 13.5 du livre «Programmation dans Scala: un guide pas à pas complet» pour plus de détails sur les modificateurs d'accès.
la source
private[this]
signifie. Notez la première phrase.Lors de l'ajout de la portée au modificateur privé ( private [X] ), il se comporte effectivement comme un X «jusqu'à», où X désigne un package, une classe ou un objet singleton englobant.
Par exemple, private [bar] , où bar est un package signifie que chaque instance de chaque classe appartenant à package bar peut accéder au membre que le modificateur restreint.
Dans le cas de private [this] , cela signifie que le membre n'est accessible que pour chaque instance. Cela devient plus clair dans l'exemple suivant:
Comme vous pouvez le voir, le deuxième Foo n'a aucun problème puisque n'importe quelle instance peut accéder au val privé i. Cependant, pour le premier Foo, il y a une erreur car chaque instance ne peut pas voir le i d'une autre instance.
C'est une bonne pratique d'écrire private [ceci] car cela impose une restriction plus importante.
la source
Dans la plupart des langages de programmation POO comme java, les champs / méthodes privés signifient que ces champs / méthodes privés ne sont pas accessibles en dehors de la classe. Cependant, les instances / objets de la même classe peuvent avoir accès aux champs privés des objets en utilisant l'opérateur d'affectation ou au moyen du constructeur de copie. Dans Scala, private [this] est un objet privé, ce qui garantit qu'aucun autre objet de la même classe ne pourra accéder aux membres private [this].
Exemple
1.Sans privé [ceci]
2.Utiliser privé [this]
Par conséquent, private [this] s'assure que le champ _password n'est accessible qu'avec this.
la source
Pour élaborer sur le problème de performance mentionné par Alexey Romanov, voici quelques-unes de mes hypothèses. Citations du livre "Programming in Scala: A Comprehensive Step-by-Step Guide, 2nd Edition" Section 18.2:
Pour le tester, ce code provoquera une erreur de compilation:
Scala se plaint
error: ambiguous reference to overloaded definition
. L'ajout d'un mot-clé override àdata_=
n'aidera pas devrait prouver que la méthode est générée par le compilateur. L'ajout d'unprivate
mot clé à une variabledata
provoquera toujours cette erreur de compilation. Cependant, le code suivant se compile correctement:Donc, je suppose que
private[this]
cela empêchera scala de générer des méthodes getter et setter. Ainsi, accéder à une telle variable économisera la surcharge de l'appel des méthodes getter et setter.la source
Il est préférable d'utiliser
private[this]
si vous prévoyez de synchroniser la variable.Voici un bon exemple du guide de style scala de l'équipe Spark :
la source