为什么dart在引用方法时会创建闭包? [英] why does dart create closures when referencing a method?

查看:72
本文介绍了为什么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语言导览页的此类引用方法会创建一个每次都关闭新文件。有人知道为什么这样做吗?我可以理解在定义方法主体时创建闭包,因为我们可以在方法主体中使用外部作用域中的变量,但是当仅引用上述方法时,为什么创建闭包时方法主体没有变化,因此不能使用该范围内可用的任何变量可以吗?我在一个上一个问题中注意到,我问这样的引用方法可以有效地将它们绑定到它们被引用。因此,在上面的示例中,如果我们调用 fnRef(),其行为将类似于 one.getMyId(),闭包也是如此仅用于绑定调用上下文? ...我很困惑:S

According to the dart language tour page referencing methods like this creates a new closure each time. Does anyone know why it does this? I can understand creating closures when defining a method body as we can use variables in an outer scope within the method body, but when just referencing a method like above, why create the closure as the method body isn't changing so it can't use any of the variables available in that scope can it? I noticed in a previous question I asked that referencing methods like this effectively binds them to the object they were referenced from. So in the above example if we call fnRef() it will behave like one.getMyId() so is the closure used just for binding the calling context? ... I'm confused :S

UPDATE

拉迪切克。所以这是否意味着:

In response to Ladicek. So does that mean that:

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是正确的:访问一个

Ladicek is right: accessing a method as a getter will automatically bind the method.

对于更新后的问题:

否。它不应使示波器保持活动状态。绑定闭包通常以调用相同名称的getter的方式实现:

No. It shouldn't keep the scope alive. Binding closures are normally implemented as if you invoked a getter of the same name:

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 函数。

When implemented this way you will not capture any variable that is alive in your useLotsOfMemory function.

即使它确实在分配闭包在 useLotsOfMemory 函数内部,尚不清楚它是否保持大量内存活动。

Even if it really was allocating the closure inside the useLotsOfMemory function, it wouldn't be clear if it kept lots of memory alive.

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

Dart does not specify how much (or how little) is captured when a closure is created. Clearly it needs to capture at least the free variables of itself. This is the minimum. The question is thus: "how much more does it capture"?

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

The general consensus seems to be to capture every variable that is free in some closure. All local variables that are captured by some closure are moved into a context object and every closure that is created will just store a link to that object.

示例:

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中,这不是必需条件,我不会依赖它。为了安全起见,我总是假设所有捕获的变量(独立于谁捕获它们)都保持活动状态。 我还要假设绑定闭包的实现类似于我上面显示的那样,并且它们使活动的内存保持在最低限度。

I have seen Scheme implementations that only captured their own free variables (splitting the context object into independent pieces), so less is possible. However in Dart this is not a requirement and I wouldn't rely on it. For safety I would always assume that all captured variables (independent of who captures them) are kept alive. I would also make the assumption that bound closures are implemented similar to what I showed above and that they keep a strict minimum of memory alive.

这篇关于为什么dart在引用方法时会创建闭包?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆