截至目前的最佳答案绝对是正确的。
我将尝试在此答案中更详细地介绍。
我会回答这个问题,但首先要说明的是:这不是 Dart 的预期编写方式,部分原因是库私有成员可以更容易地定义像==
. (无法看到第二个对象的私有变量进行比较。)
既然我们已经解决了这个问题,我将首先向您展示它是如何完成的(library-private 而不是 class-private),然后向您展示如何使变量 class-private if你还是真的想要那个。开始了。
如果一个类无法查看另一个类的变量,您可能会问自己它们是否真的属于同一个库:
//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
}
那应该很好。但是,如果您真的想要私有类数据:
虽然技术上不允许您创建私有变量,但您可以使用以下闭包技术来模拟它。
(然而,你应该仔细考虑你是否真的需要它,以及是否有更好、更类似于 Dart 的方式来完成你想要完成的事情!)
//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.
}
是的。请小心并尝试遵循语言的最佳实践,您应该会没事的。
编辑
显然有一个新的 typedef 语法是 Dart 2 的首选。如果你使用的是 Dart 2,你应该使用它。或者,更好的是,使用内联函数类型。
如果您使用第二个,它将不那么冗长,但其他问题仍然存在。