List.forEach无法修改元素?

时间:2014-03-05 21:58:29

标签: arrays foreach dart

我正在尝试创建一个列表列表,以模仿Dart中2D阵列的功能,而我在找出如何使其工作时遇到了麻烦。

我最初使用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()构造函数这样的东西 - 这就是我开始构建其他功能的方式。

编辑:好的,我想我现在明白了。参数是“pass-by-sharing”,这意味着对该对象的引用的副本。这意味着您可以修改参数指向的可变对象的成员(如下所示):

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

但尝试更改o指向的内容在退出函数后不会更改参数,例如:

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

3 个答案:

答案 0 :(得分:3)

Dart没有变量引用,所有元素都作为对象的引用传递,而不是传递给变量。 (换句话说,Dart纯粹是像Java和JavaScript一样的“分享呼叫”)。

这意味着e回调的forEach参数只是一个普通的局部变量,并且分配给它在回调之外没有任何影响。迭代器也是如此:它们返回迭代中的值,但之后没有引用回迭代。

当你执行“read-modify-write”时,你想要的是双循环。您从列表中读取值,修改它并使用列表的索引集运算符将其存储回列表中。

我知道你知道List.filled,但是对于其他读者,我会给出一行代码来创建初始化为1值的二维数组:

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

答案 1 :(得分:2)

这是因为e仅是对ListcurrentMap的引用,而不是currentMap项目的引用。
您将引用的副本更新为List,但此引用与currentMap没有关联 在循环之后,e只是收集垃圾。

答案 2 :(得分:1)

这是因为枚举器的工作原理,我相信因为枚举器是不可变的当你在foreach中处理它时,你无法修改集合项......删除成员等。

另见:

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

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