2014-03-05 68 views
3

我試圖創建一個列表列表來模仿Dart中的2D數組的功能,並且我一直在弄清楚如何使其工作。List.forEach無法修改元素?

我最初使用List.forEach爲了創建列表並填充它們,但在每個循環後,就好像我從未創建列表。下面是看起來像什麼代碼:

currentMap = new List<List<int>>(height); 
currentMap.forEach((e) { 
    e = new List<int>(width); 
    e.forEach((f) { 
     f = 1; 
    }); 
}); 

印刷currentMap導致的null列表。這是我現在有:

currentMap = new List<List<int>>(height); 
for(int i = 0; i < height; i++) { 
    currentMap[i] = new List<int>(width); 
    for(int j = 0; j < width; j++) { 
     currentMap[i][j] = 1; 
    } 
} 

這工作完全符合我的預期。

據我所知,這可能是一個非常基本的問題,我假設forEach不允許你修改元素,但我想對此做一些確認,並且Dart API文檔除了使用短語「將函數f應用於每個元素......」,這對我來說可能並不清楚。

此外,我知道像List.filled()構造函數的事情 - 這是我如何開始構建其他功能。

編輯:好吧,我想我現在明白了。參數是「通過共享」,這意味着對該對象的引用的副本被創建。這意味着你可以修改由參數指向了一個可變對象的成員(如下):

void function(MyObject o) { 
    o.x = 5; 
} 

而是試圖改變什麼o點退出函數,這樣以後就不會改變參數因爲這樣:

void function(MyObject o) { 
    MyObject p = new MyObject(); 
    o = p; 
} 

回答

3

Dart沒有變量引用,所有元素都作爲對象的引用而不是變量傳遞。 (換句話說,Dart完全像Java和JavaScript一樣是「共享呼叫」)。

這意味着回調參數只是一個正常的局部變量,並且賦值給它在回調之外沒有任何效果。迭代器也是如此:它們返回迭代器中的值,但之後沒有引用回到迭代器。

當您執行「讀取 - 修改 - 寫入」時,雙循環就是您想要的。您從列表中讀取值,使用列表的索引集操作符對其進行修改並將其存儲回列表中。

我知道你知道List.filled,但只是爲了其他讀者,我給了一個班輪創建初始化爲1值的二維數組:

currentMap = new List.generate(height, (_) => new List.filled(width, 1)); 
+0

好吧,讓我們看看我是否有這個權利:原始類型是傳遞值,對象是傳遞-參考。在我的forEach中,我爲每個元素創建一個列表,因爲這些列表是通過引用傳遞的對象,但內部循環不會修改這些值,因爲它們是整數。這聽起來是對的嗎?我非常感謝你的迴應。這很有道理。 –

+0

飛鏢只通過引用沒有傳遞值。但是,在列表中沒有指向值的參考,e是參考的副本。您可以爲e分配一個新值,但這不會影響列表。 –

+0

我欣賞所有的評論。你能解釋「參考」是什麼意思嗎?當我聽到我認爲類似於指針的東西時,所以我認爲原件會被修改,但顯然情況並非如此。 –

1

這是因爲一個枚舉器是如何工作的,我相信,因爲枚舉是不可變的,不能修改的藏品時,它在foreach正在處理...刪除成員等。

參見:

http://msdn.microsoft.com/en-us/library/ttw7t8t6.aspx

What is the best way to modify a list in a 'foreach' loop?

+0

感謝您的快速響應和鏈接。我在Dart的API文檔中找到了此行,用於Iterable : 「通常不允許在迭代迭代時修改這些集合。」 這並不能解釋爲什麼它首先讓我這樣做,但是的確解釋說,也許首先嚐試去做並不是一個好主意。 –

2

這是因爲e只對List一個參考currentMap不是一個currentMap項目。
您將引用的副本更新爲List,但該引用與currentMap無關。
循環後,e只是垃圾收集。

+0

如果是這種情況,那麼爲什麼這個聲明有效? e =新列表(寬); 我明白,f只是一個複製的值,但它似乎好像我可以修改e的值。感謝您的迴應! –

+0

正如lrn寫道的。 e和f是用指向列表項的值初始化的局部變量。您可以重新分配給他們想要的東西(如果類型不適合,分析儀會發出錯誤),但它不會更改爲列表項指向的值。 –

+0

好的,這是有道理的,我認爲我錯誤地說聲明影響了名單。當我有機會時,我將不得不玩這個。感謝您的澄清! –