Ich möchte eine private Variable erstellen, kann dies aber nicht.
Hier ist mein Code:
void main() {
var b = new B();
b.testB();
}
class A {
int _private = 0;
testA() {
print('int value: $_private');
_private = 5;
}
}
class B extends A {
String _private;
testB() {
_private = 'Hello';
print('String value: $_private');
testA();
print('String value: $_private');
}
}
Wenn ich diesen Code ausführe, erhalte ich das folgende Ergebnis:
String value: Hello
int value: Hello
Breaking on exception: type 'int' is not a subtype of type 'String' of 'value'.
Außerdem erhalte ich beim Bearbeiten dieses Quellcodes keine Fehler oder Warnungen.
Wie kann ich eine private Variable in Dart erstellen?
Datenschutz in Dart besteht eher in der Bibliothek als auf Klassenebene.
Wenn Sie Klasse A in eine separate Bibliotheksdatei einfügen (z. B.
other.dart
), z.library other; class A { int _private = 0; testA() { print('int value: $_private'); // 0 _private = 5; print('int value: $_private'); // 5 } }
und importieren Sie es dann in Ihre Haupt-App, z.
import 'other.dart'; void main() { var b = new B(); b.testB(); } class B extends A { String _private; testB() { _private = 'Hello'; print('String value: $_private'); // Hello testA(); print('String value: $_private'); // Hello } }
Sie erhalten die erwartete Ausgabe:
String value: Hello int value: 0 int value: 5 String value: Hello
quelle
Die Top-Antwort ist ab sofort definitiv richtig.
Ich werde versuchen, in dieser Antwort näher darauf einzugehen.
Ich werde die Frage beantworten, aber damit beginnen: So soll Dart einfach nicht geschrieben werden, auch weil bibliotheksprivate Mitglieder es einfacher machen, Operatoren wie zu definieren
==
. (Private Variablen eines zweiten Objekts konnten für den Vergleich nicht angezeigt werden.)Nachdem wir das aus dem Weg geräumt haben, zeige ich Ihnen zunächst, wie es gemacht werden soll (bibliotheksprivat statt klassenprivat), und zeige Ihnen dann, wie Sie eine Variable klassenprivat machen, wenn das willst du immer noch wirklich. Auf geht's.
Wenn eine Klasse keine geschäftlichen Variablen in einer anderen Klasse sieht, fragen Sie sich möglicherweise, ob sie wirklich zur selben Bibliothek gehören:
//This should be in a separate library from main() for the reason stated in the main method below. class MyClass { //Library private variable int _val = 0; int get val => _val; set val(int v) => _val = (v < 0) ? _val : v; MyClass.fromVal(int val) : _val = val; } void main() { MyClass mc = MyClass.fromVal(1); mc.val = -1; print(mc.val); //1 //main() MUST BE IN A SEPARATE LIBRARY TO //PREVENT MODIFYING THE BACKING FIELDS LIKE: mc._val = 6; print(mc.val); //6 }
Das sollte gut sein. Wenn Sie jedoch wirklich private Klassendaten möchten:
Obwohl Sie technisch private Variablen zu erstellen ist nicht erlaubt, Sie könnten es emulieren die folgende Verschlusstechnik.
(Sie sollten jedoch sorgfältig überlegen, ob Sie es wirklich brauchen und ob es einen besseren, dartartigeren Weg gibt, um das zu tun, was Sie erreichen wollen!)
//A "workaround" that you should THINK TWICE before using because: //1. The syntax is verbose. //2. Both closure variables and any methods needing to access // the closure variables must be defined inside a base constructor. //3. Those methods require typedefs to ensure correct signatures. typedef int IntGetter(); typedef void IntSetter(int value); class MyClass { IntGetter getVal; IntSetter setVal; MyClass.base() { //Closure variable int _val = 0; //Methods defined within constructor closure getVal = ()=>_val; setVal = (int v) => _val = (v < 0) ? _val : v; } factory MyClass.fromVal(int val) { MyClass result = MyClass.base(); result.setVal(val); return result; } } void main() { MyClass mc = MyClass.fromVal(1); mc.setVal(-1); //Fails print(mc.getVal()); //On the upside, you can't access _val //mc._val = 6; //Doesn't compile. }
Also ja. Seien Sie vorsichtig und versuchen Sie, die Best Practices der Sprache zu befolgen. Es sollte Ihnen gut gehen.
BEARBEITEN
Anscheinend gibt es eine neue typedef-Syntax, die für Dart 2 bevorzugt wird. Wenn Sie Dart 2 verwenden, sollten Sie diese verwenden. Oder, noch besser, verwenden Sie Inline-Funktionstypen.
Wenn Sie die zweite verwenden, ist sie weniger ausführlich, aber die anderen Probleme bleiben bestehen.
quelle
_val
implizit einen Getter und einen Setter?MyClass.fromVal(int val) : _val = val;
- Ist dies der Weg, um statische Methoden zu erstellen ?In dart wird _ vor dem Variablennamen verwendet, um ihn als privat zu deklarieren. Im Gegensatz zu anderen Programmiersprachen bedeutet privat nicht, dass es nur für die Klasse verfügbar ist, in der es sich befindet. Privat bedeutet, dass es in der Datei, in der es sich befindet, zugänglich ist und für andere Dateien nicht zugänglich ist.
quelle