2013-05-09 28 views
2
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問題中,我問過像這樣的引用方法有效地將它們綁定到它們所引用的對象。所以在上面的例子中,如果我們調用fnRef()它將表現得像one.getMyId()那麼閉包只用於綁定調用上下文嗎? ......我很困惑:S爲什麼dart在引用方法時創建閉包?

UPDATE

針對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; 
} 

回答

4

Ladicek是正確的:訪問方法的吸氣劑將自動綁定方法。

針對更新的問題:

號它不應該保留的範圍還活着。

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函數內關閉,那就不是很清楚,如果它保留大量內存活。

飛鏢不指定創建時關閉多少(或多麼少)抓獲。顯然它需要至少捕獲自身的自由變量。這是最低限度。因此問題是:「它還捕獲了多少」?

一般的共識似乎是捕獲在一些封閉免費的每個變量。所有由某個閉包捕獲的局部變量都被移入一個上下文對象,並且每個創建的閉包都會存儲一個指向該對象的鏈接。

實施例:

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中這不是一個要求,我不會依賴它。爲了安全起見,我總是會假設所有捕獲的變量(與誰捕獲它們無關)都保持活躍。 我也會假設綁定關閉的實現類似於我在上面展示的內容,並且它們保持嚴格的最小內存活着。

2

這是正確的 - 閉包捕獲方法將被調用的對象。

相關問題