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/