Dart中矩阵元素更新结果因初始化方式不同的问题咨询
Dart二维矩阵初始化的差异及解决方案
先看你提供的测试代码:
void probtest() { List<List<int>> mat1 = List.filled(3, List.filled(3, -1)); List<List<int>> mat2 = [ [-1, -1, -1], [-1, -1, -1], [-1, -1, -1] ]; print(mat1); print(mat2); mat1[0][0] = 1; mat2[0][0] = 1; print(mat1); print(mat2); }
对应的输出差异很明显:修改mat1[0][0]会导致所有子列表的第0个元素都变成1,而mat2只有目标位置改变。
问题1:两种初始化方式为何结果不同?
核心原因是**List.filled的填充逻辑是复用同一个对象引用**:
- 当你执行
List.filled(3, List.filled(3, -1))时,外层列表的3个元素,都是指向同一个内层列表实例的引用。也就是说,mat1[0]、mat1[1]、mat1[2]其实是同一个列表对象,修改其中任意一个的元素,另外两个都会同步变化,因为它们本质是同一个东西。 - 而用字面量
[[-1,-1,-1], [-1,-1,-1], [-1,-1,-1]]创建时,每一组[-1,-1,-1]都是单独创建的新列表,相互独立,修改其中一个不会影响其他子列表。
问题2:无需手动写字面量,如何创建可独立修改的大规模矩阵?
推荐用List.generate来创建,它会为外层列表的每个元素执行一次回调,每次都生成新的内层列表,保证子列表相互独立:
// 创建n行m列的矩阵,初始值为-1 int rows = 100; int cols = 100; List<List<int>> mat = List.generate(rows, (_) => List.filled(cols, -1));
这样创建的矩阵,修改任意mat[i][j]都只会影响对应位置的元素,和你用字面量创建的mat2行为一致。
另外也可以用循环手动构建:
List<List<int>> mat = []; for (int i = 0; i < rows; i++) { mat.add(List.filled(cols, -1)); }
效果和List.generate完全一样,只是写法更繁琐,推荐用List.generate更简洁。
内容的提问来源于stack exchange,提问作者Graham Hopper
相关产品推荐
相关产品推荐

