In Scala sehe ich eine Funktion als objektprivate Variable. Aufgrund meines nicht sehr umfangreichen Java-Hintergrunds habe ich gelernt, alles zu schließen (privat zu machen) und bei Bedarf zu öffnen (Accessoren bereitzustellen). Scala führt einen noch strengeren Zugriffsmodifikator ein. Sollte ich es immer standardmäßig verwenden? Oder sollte ich es nur in bestimmten Fällen verwenden, in denen ich das Ändern des Feldwerts auch für Objekte derselben Klasse explizit einschränken muss? Mit anderen Worten, wie soll ich wählen
class Dummy {
private var name = "default name"
}
class Dummy {
private[this] var name = "default name"
}
Das zweite ist strenger und ich mag es, aber sollte ich es immer verwenden oder nur, wenn ich einen starken Grund habe?
BEARBEITET: Wie ich hier sehe ,private[this]
ist nur ein Teilfall und stattdessen this
kann ich andere Modifikatoren verwenden: "Paket, Klasse oder Singleton-Objekt". Also lasse ich es für einen besonderen Fall.
Antworten:
Ich denke nicht, dass es zu wichtig ist, da Änderungen nur eine Klasse berühren. So ist der wichtigste Grund zu bevorzugen
private
überprotected
überpublic
keine Anwendung findet.Verwenden
private[this]
Sie diese Option dort, wo die Leistung wirklich wichtig ist (da Sie auf diese Weise direkten Zugriff auf das Feld anstelle von Methoden erhalten). Ansonsten nur siedeln sich auf einen Stil , damit die Leute nicht brauchen , um herauszufinden , warum diese Eigenschaft istprivate
und dass man istprivate[this]
.quelle
private
ohnehin generierten Accessor-Methodenaufrufe einbinden, sodass die Auswirkung Null oder zumindest sehr, sehr gering sein sollte.Es gibt einen Fall, in
private[this]
dem Code kompiliert werden muss. Dies hat mit einer Wechselwirkung von Varianznotation und veränderlichen Variablen zu tun. Betrachten Sie die folgende (nutzlose) Klasse:Diese Klasse enthält also einen optionalen Wert, gibt ihn als Option zurück und ermöglicht dem Benutzer den Aufruf
makeEmpty
zum Löschen des Werts (daher der var). Wie bereits erwähnt, ist dies nutzlos, außer um den Punkt zu demonstrieren.Wenn versuchen Sie diesen Code kompilieren mit ,
private
anstattprivate[this]
es mit der folgenden Fehlermeldung fehlschlagen:Dieser Fehler tritt auf, weil value eine veränderbare Variable für den kovarianten Typ T (+ T) ist, die normalerweise ein Problem darstellt, sofern sie nicht für die Instanz mit als privat markiert ist
private[this]
. Der Compiler hat eine spezielle Behandlung in seiner Varianzprüfung, um diesen speziellen Fall zu behandeln.Es ist also esoterisch, aber es gibt einen Fall, in dem
private[this]
es erforderlich istprivate
.quelle
private var name
ist von jeder Methode desclass Dummy
(und seines Begleitersobject Dummy
) zugänglich .private[this] var name
ist nur überthis
Objektmethoden zugänglich , nicht über andere Objekte vonclass Dummy
.quelle
Sie können also jedes Mal privat [dies] tun, aber Sie können ein Problem haben, wenn Sie es weiterleiten müssen
quelle
private[this]
ist nicht gleichprotected[this]
.protected[this]
Ermöglicht Unterklasseninstanzen den Zugriff auf das Mitglied.this.y == that.y
weder privat noch privat [dies] verwenden, ich habe gerade beides versuchtDies wurde mit Scala 2.11.5 getestet. Betrachten Sie den folgenden Code
Es wird kompiliert und funktioniert als dieser Java (1.8) Code
Wenn Sie jedoch den Modifikator '[this]' verwenden, wird der folgende Code nicht kompiliert
Dies liegt daran, dass im ersten Fall auf 'x' auf Klassenebene zugegriffen werden kann, während es im zweiten Fall eine strengere Instanzebene ist. Dies bedeutet, dass auf 'x' nur von der Instanz aus zugegriffen werden kann, zu der es gehört. "This.x" ist also in Ordnung, "other.x" jedoch nicht.
Weitere Informationen zu Zugriffsmodifikatoren finden Sie in Abschnitt 13.5 des Buches "Programmieren in Scala: Eine umfassende Schritt-für-Schritt-Anleitung".
quelle
private[this]
bedeutet. Beachten Sie den ersten Satz.Wenn Sie den Bereich zum privaten Modifikator ( privat [X] ) hinzufügen , verhält er sich effektiv wie ein "bis zu" X, wobei X ein umschließendes Paket, eine Klasse oder ein Singleton-Objekt bezeichnet.
Zum Beispiel privaten [bar] , in denen bar ein Paket bedeutet, dass jede Instanz jeder Klasse zu Paket gehör bar zugreifen kann je nachdem , welches Mitglied die Modifikator beschränken ist.
Im Fall von privat [dies] bedeutet dies, dass das Mitglied nur für jede Instanz zugänglich ist. Dies wird im folgenden Beispiel deutlicher:
Wie Sie sehen können, hat der zweite Foo kein Problem, da jede Instanz auf den privaten Wert i zugreifen kann. Beim ersten Foo tritt jedoch ein Fehler auf, da nicht jede Instanz das i einer anderen Instanz sehen kann.
Es ist eine gute Praxis, privat [dies] zu schreiben, da dies eine größere Einschränkung darstellt.
quelle
In den meisten OOP-Programmiersprachen wie Java bedeuten private Felder / Methoden, dass auf diese privaten Felder / Methoden außerhalb der Klasse nicht zugegriffen werden kann. Instanzen / Objekte derselben Klasse können jedoch mithilfe des Zuweisungsoperators oder mithilfe eines Kopierkonstruktors auf die privaten Felder von Objekten zugreifen. In Scala ist private [this] ein Objekt private, wodurch sichergestellt wird, dass kein anderes Objekt derselben Klasse auf private [this] -Mitglieder zugreifen kann.
Beispiel
1. Ohne private [dies]
2.Verwenden Sie private [this]
Daher stellt private [this] sicher, dass das Feld _password nur damit zugänglich ist.
quelle
Um auf das Performance-Problem einzugehen, das Alexey Romanov erwähnt hat, hier einige meiner Vermutungen. Zitate aus dem Buch "Programmieren in Scala: Eine umfassende Schritt-für-Schritt-Anleitung, 2. Auflage" Abschnitt 18.2:
Zum Testen verursacht dieser Code einen Kompilierungsfehler:
Scala beschwert sich über
error: ambiguous reference to overloaded definition
. Das Hinzufügen eines Überschreibungsschlüsselworts zudata_=
nicht hilfreich sollte beweisen, dass die Methode vom Compiler generiert wird. Das Hinzufügen einesprivate
Schlüsselworts zur Variablendata
führt weiterhin zu diesem Kompilierungsfehler. Der folgende Code wird jedoch problemlos kompiliert:Ich denke also,
private[this]
wird Scala daran hindern, Getter- und Setter-Methoden zu generieren. Der Zugriff auf eine solche Variable spart somit den Aufwand für den Aufruf der Getter- und Setter-Methode.quelle
Es ist besser zu verwenden,
private[this]
wenn Sie die Variable synchronisieren möchten.Hier ein gutes Beispiel aus dem Scala Style Guide des Spark-Teams :
quelle