You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 22:05:40