closures - 为什么 dart 在引用方法时创建闭包?

标签 closures dart

void main() {
  A one = new A(1);
  A two = new A(2);

  var fnRef = one.getMyId;        //A closure created here
  var anotherFnRef = two.getMyId; //Another closure created here
}

class A{
  int _id;
  A(this._id);
  int getMyId(){
    return _id;
  }
}

根据dart language tour像这样的页面引用方法每次都会创建一个新的闭包。有谁知道它为什么这样做?我可以理解在定义方法主体时创建闭包,因为我们可以在方法主体内的外部范围内使用变量,但是当仅引用上述方法时,为什么要创建闭包,因为方法主体没有改变,所以它不能使用该范围内可用的任何变量可以吗?我注意到 previous问题 我问这样的引用方法有效地将它们绑定(bind)到引用它们的对象。所以在上面的例子中,如果我们调用 fnRef(),它的行为就像 one.getMyId() 那么闭包是否只用于绑定(bind)调用上下文? ...我很困惑:S

更新

回应 Ladicek。那么这是否意味着:

void main(){
    var fnRef = useLotsOfMemory();
    //did the closure created in the return statement close on just 'aVeryLargeObj'
    //or did it close on all of the 'veryLargeObjects' thus keeping them all in memory 
    //at this point where they aren't needed
}

useLotsOfMemory(){
    //create lots of 'veryLarge' objects
    return aVeryLargeObj.doStuff;
}

最佳答案

Ladicek 是对的:将方法作为 getter 访问将自动绑定(bind)该方法。

针对更新后的问题:

没有。它不应该使范围保持事件状态。绑定(bind)闭包的实现通常就像调用同名的 getter 一样:

class A{
  int _id;
  A(this._id);
  int getMyId() => _id;

  // The implicit getter for getMyId. This is not valid
  // code but explains how dart2js implements it. The VM has
  // probably a similar mechanism.
  Function get getMyId { return () => this.getMyId(); }
}

当以这种方式实现时,您将不会捕获任何在您的 useLotsOfMemory 函数中存在的变量。


即使它真的在 useLotsOfMemory 函数中分配闭包,也不清楚它是否保留了大量内存。

Dart 没有指定在创建闭包时捕获多少(或多少)。显然,它至少需要捕获自身的自由变量。这是最低要求。因此,问题是:“它还捕获了多少”?

普遍的共识似乎是捕获某些 闭包中空闲的每个变量。某些闭包捕获的所有局部变量都被移入上下文对象,并且创建的每个闭包将只存储指向该对象的链接。

例子:

foo() {
  var x = new List(1000);
  var y = new List(100);
  var z = new List(10);
  var f = () => y;  // y is free here.
  // The variables y and z are free in some closure.
  // The returned closure will keep both alive.
  // The local x will be garbage collected.
  return () => z;  // z is free here.
}

我见过 Scheme 实现只捕获它们自己的自由变量(将上下文对象拆分成独立的部分),所以可能更少。但是在 Dart 中,这不是必需的,我不会依赖它。为了安全起见,我总是假设所有捕获的变量(独立于捕获它们的人)都保持事件状态。 我还会假设绑定(bind)闭包的实现方式与我上面展示的类似,并且它们会严格保持最少的内存。

关于closures - 为什么 dart 在引用方法时创建闭包?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16458199/

相关文章:

php - 如何在没有局部变量的情况下重新设计这段 PHP 代码?

Ruby 相当于 python 非本地

swift - 回调/闭包如何知道在异步调用完成后等待?

flutter - Timeline.dart 在 dart 中有何用途?

flutter - 对象属性可以用作函数参数吗?

layout - 使用 Align 或使用 Positioned flutter 有什么区别

rust - 如何从 Rust 中的 Fn 闭包内部更改变量?

javascript - ES5构造函数中定义的私有(private)变量之谜

Dart:条目前置后的 DoubleLinkedQueue 长度

dart - AngularDart 中的表单验证/字段验证失败且没有错误消息