48 dart
我想创建一个私有变量,但我不能.
这是我的代码:
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');
}
}
Run Code Online (Sandbox Code Playgroud)
当我运行此代码时,我得到以下结果:
String value: Hello
int value: Hello
Breaking on exception: type 'int' is not a subtype of type 'String' of 'value'.
Run Code Online (Sandbox Code Playgroud)
编辑此源代码时,我也没有收到任何错误或警告.
如何在Dart中创建私有变量?
mez*_*oni 81
来自Dart文档:
与Java不同,Dart没有关键字public,protected和private.如果标识符以下划线开头
_,则它对其库是私有的.
库不仅提供API,还是隐私单元:以下划线开头的标识符_仅在库内可见.
Chr*_*ett 27
Dart中的隐私存在于图书馆,而不是班级.
如果您要将A类放入单独的库文件(例如other.dart),例如:
library other;
class A {
int _private = 0;
testA() {
print('int value: $_private'); // 0
_private = 5;
print('int value: $_private'); // 5
}
}
Run Code Online (Sandbox Code Playgroud)
然后将其导入您的主应用程序,例如:
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
}
}
Run Code Online (Sandbox Code Playgroud)
你得到了预期的输出:
String value: Hello
int value: 0
int value: 5
String value: Hello
Run Code Online (Sandbox Code Playgroud)
在dart' _' 中使用在 之前将variable name其声明为private。不像其他的编程语言,在这里private并不意味着它仅适用于类是在私人意味着它是在文件访问和其他文件无法访问。
到目前为止,最高答案肯定是正确的。
我将尝试在此答案中更详细地说明。
我将回答这个问题,但首先提出:这不是Dart的编写意图,部分原因是私有库成员使像这样的定义运算符更加容易==。(比较时看不到第二个对象的私有变量。)
现在我们已经解决了这个问题,我将首先向您展示它是如何完成的(库私有而不是class-private),然后向您展示如何使变量成为class-private。你仍然真的想要那个。开始了。
如果一个类没有业务看到另一个类上的变量,则您可能会问自己,它们是否真正属于同一库:
//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
}
Run Code Online (Sandbox Code Playgroud)
那应该很好。但是,如果您确实想要私有类数据:
尽管从技术上讲不允许您创建私有变量,但是您可以使用以下闭包技术对其进行仿真。
(但是,您应该仔细考虑是否真的需要它,以及是否有更好的,更像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.
}
Run Code Online (Sandbox Code Playgroud)
是的。只要小心并尝试遵循该语言的最佳实践,就可以了。
编辑
显然,有一种新的typedef语法是Dart 2首选的。如果您使用的是Dart 2,则应该使用它。或者,甚至更好地使用内联函数类型。
如果您使用第二个,它的详细程度会降低,但是其他问题仍然存在。
| 归档时间: |
|
| 查看次数: |
20863 次 |
| 最近记录: |