likes
comments
collection
share

Dart clousure in practice

作者站长头像
站长
· 阅读数 1

理论部分我就不详述了,参考其他大佬的教程: flutter.cn/community/t…

首先想聊下dart的参数传递问题。 由于dart没法打印出指针,所以没法输出真正的内存地址,不过我猜测针对字面量,每个字面量实际都是一个新的对象,赋值后变量指针就指向这个新的对象。如下所示:

  1. v1++之后v1实际指向了一个新的对象,所以v1=1,v2=0;
  2. 自建对象则没有这个问题,估计自建对象在堆上新建,赋值时新旧变量都指向了堆上的对象(或者说新旧变量存储了该对象在堆上的地址)。
// 字面量赋值
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();
}

总结

  1. dart中函数是一等公民,可以作为变量、函数参数和返回值。
  2. 可以使用闭包创建一个自增器,设置初始num, 后续调用得到自增值。
  3. 在闭包中直接引用对象,会导致内外部均能影响该对象。