Dart clousure in practice
理论部分我就不详述了,参考其他大佬的教程: flutter.cn/community/t…
首先想聊下dart的参数传递问题。 由于dart没法打印出指针,所以没法输出真正的内存地址,不过我猜测针对字面量,每个字面量实际都是一个新的对象,赋值后变量指针就指向这个新的对象。如下所示:
- v1++之后v1实际指向了一个新的对象,所以v1=1,v2=0;
- 自建对象则没有这个问题,估计自建对象在堆上新建,赋值时新旧变量都指向了堆上的对象(或者说新旧变量存储了该对象在堆上的地址)。
// 字面量赋值
void main() {
int v1 = 0;
int v2 = v1;
v1++;
print('v1:$v1 v2:$v2'); // v1:1 v2:0
}
// 自建对象赋值
void main() {
var v1 = Counter();
var v2 = v1;
print('v1.count:${v1.count} v2.count:${v2.count}'); // v1.count:0 v2.count:0
v1.plus();
print('v1.count:${v1.count} v2.count:${v2.count}'); // v1.count:1 v2.count:1
}
class Counter {
var count = 0;
void plus() => count++;
}
闭包引用变量
情况1: 闭包影响了外部变量
void main() {
var value = 0;
var Counter = () {
return () {
value++;
return value;
};
};
var counter = Counter();
print(counter()); // 1
print(counter()); // 2
print(counter()); // 3
print('origin:$value'); // origin: 3
}
情况2: 未影响外部变量
闭包内创建局部变量,将外部变量赋值给局部变量 闭包调用不影响外部变量。
void main() {
var value = 0;
var Counter = () {
// 新建局部变量,避免影响外部变量
var val1 = value;
return () {
val1++;
return val1;
};
};
var counter = Counter();
print(counter()); // 1
print(counter()); // 2
print(counter()); // 3
print('origin:$value'); // origin: 0
}
情况3:闭包内使用自建对象
闭包内引用自建对象,闭包内外共享了该对象 所以闭包内外均能改变自建对象
void main() {
// 引用一个对象, 在闭包内外操作该对象,均能改变
var originCounter = Counter();
var selfCounter = () {
Counter counter = originCounter;
return () {
print(counter.plus());
};
};
var counter = selfCounter();
print(originCounter.num); // 0
counter(); // 1
print(originCounter.num); // 1
print(originCounter.plus()); // 2
counter(); // 3
print(originCounter.num); // 3
counter(); // 4
}
class Counter {
var num = 0;
int plus() {
num++;
return num;
}
}
闭包实践
一般使用typedef进行定义再使用
/// Signature of callbacks that have no arguments and return no data.
typedef VoidCallback = void Function();
void doSth(String origin, VoidCallback finish) {
// 逻辑处理...
finish();
}
总结
- dart中函数是一等公民,可以作为变量、函数参数和返回值。
- 可以使用闭包创建一个自增器,设置初始num, 后续调用得到自增值。
- 在闭包中直接引用对象,会导致内外部均能影响该对象。
转载自:https://juejin.cn/post/6912080631706943495