List.forEach无法修改元素? [英] List.forEach unable to modify element?
问题描述
我正在尝试创建一个列表列表来模仿Dart中2D阵列的功能,并且在弄清楚如何使其工作方面遇到了一段时间。
I'm attempting to create a list of lists to imitate the functionality of a 2D array in Dart, and I was having trouble for a while figuring out how to make it work.
我最初使用 List.forEach
来创建列表并填充列表,但是在每次循环之后,好像我从未创建过列表。代码如下所示:
I originally used List.forEach
in order to create the lists and fill them, but after each loop, it's as if I never created the lists. Here's what that code looked like:
currentMap = new List<List<int>>(height);
currentMap.forEach((e) {
e = new List<int>(width);
e.forEach((f) {
f = 1;
});
});
打印 currentMap
会生成 null
。这就是我现在拥有的东西:
Printing currentMap
resulted in a list of null
. Here's what I have now:
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;
}
}
此功能完全符合我的预期。
This works exactly as I expected it to.
我了解这可能是一个非常基本的问题,我假设 forEach
不允许您修改元素,但是我想对此进行确认,Dart API文档未指定,只是带有短语将函数f附加到每个元素...,这可能对我来说并不明确。
I understand that this is probably a very basic issue, and I am assuming that forEach
does not allow you to modify the element, but I wanted some confirmation on that, and the Dart API docs do not specify except with the phrase "apples the function f to each element..." which may just not be clear to me.
此外,我知道类似 List.filled()
构造函数的方法-这就是我开始朝着其他功能。
Also, I am aware of things like the List.filled()
constructor -- this is just how I am starting to build towards other functionality.
编辑:好的,我想我现在明白了。参数是 pass-by-sharing(通过共享),这意味着将复制对对象的引用。这意味着您可以修改参数所指向的可变对象的成员(如下所示):
Okay, I think I understand now. Arguments are "pass-by-sharing" which means that a copy of a reference to the object is made. This means that you can modify a member of a mutable object that is pointed to by the argument (as follows):
void function(MyObject o) {
o.x = 5;
}
,但尝试更改 o
指向退出函数后不会更改参数,例如:
but trying to change what o
points to will not change the argument after exiting the function, such as this:
void function(MyObject o) {
MyObject p = new MyObject();
o = p;
}
推荐答案
Dart可以没有变量引用,所有元素都作为对对象而不是变量的引用传递。 (换句话说,Dart就像Java和JavaScript一样,都是共享呼叫。)
Dart does not have variable references, all elements are passed as a reference to an object, not to a variable. (In other words, Dart is purely "call-by-sharing" like both Java and JavaScript).
这意味着 e
forEach
回调的code>参数只是普通的局部变量,对其赋值在回调之外没有任何作用。迭代器也是如此:它们返回可迭代对象中的值,但此后没有对可迭代对象的引用。
That means that the e
parameter to the forEach
callback is just a normal local variable, and assigning to it has no effect outside the callback. The same goes for iterators: they return the value in the iterable, but it has no reference back to the iterable after that.
双循环是您想要的东西做读-修改-写。您从列表中读取了一个值,对其进行了修改,然后使用列表的索引集运算符将其存储回列表中。
The double loop is what you want when you do "read-modify-write". You read a value from the list, modify it and store it back into the list using the list's index-set operator.
我知道您知道 List.filled
,但仅针对其他读者,我将提供一线内容以创建初始化为 1
值的二维数组:
I know you know about List.filled
, but just for other readers, I'll give the one-liner to create the two-dimensional array initialized to 1
values:
currentMap = new List.generate(height, (_) => new List.filled(width, 1));
这篇关于List.forEach无法修改元素?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!