Dart空安全迁移问题:Connect Four游戏分数列表赋值报错
Dart空安全迁移:Connect Four游戏分数列表修复方案
我有一款未启用空安全时正常运行的Connect Four游戏,迁移到Dart空安全模式时遇到两个核心问题:
- 原代码中
scores[i] = null;无法在List<double>类型上使用,删除该语句会导致CPU在必败场景冻结 - 改为
List<double?>后,scores[i] +=/scores[i] -=操作报错,且_getBestScoreIndex方法中分数的非空判断和大小比较无法正常执行
核心修复思路
- 保留
List<double?>类型存储分数,用null标记无效列(无法落子的列) - 对有效列的分数提前初始化默认值,确保执行
+=/-=时变量非null - 在分数比较逻辑中明确处理null值,仅对有效分数进行判断
修改后的完整代码
int _compute(Board board, int step, int deepness, List<double?> scores) { for (var i = 0; i < 7; ++i) { final boardCopy = board.clone(); final target = boardCopy.getColumnTarget(i); if (target == -1) { scores[i] = null; // 标记无效列 continue; } // 初始化有效列的分数为0.0(避免null导致运算符报错) if (scores[i] == null) { scores[i] = 0.0; } final coordinate = Coordinate(i, target); boardCopy.setBox(coordinate, player); if (boardCopy.checkWinner(coordinate, player)) { // 非空断言:逻辑上此处scores[i]已初始化,不可能为null scores[i]! += deepness / (step + 1); continue; } for (var j = 0; j < 7; ++j) { final targetJ = boardCopy.getColumnTarget(j); if (targetJ == -1) { continue; } final coordinateJ = Coordinate(j, targetJ); boardCopy.setBox(coordinateJ, otherPlayer); if (boardCopy.checkWinner(coordinateJ, otherPlayer)) { // 非空断言:同上,此处scores[i]已初始化 scores[i]! -= deepness / (step + 1); continue; } if (step + 1 < deepness) { _compute(board, step + 1, deepness, scores); } } } return _getBestScoreIndex(scores); } int _getBestScoreIndex(List<double?> scores) { // 找到第一个有效分数的索引 int bestScoreIndex = scores.indexWhere((s) => s != null); // 防御性处理:如果所有分数都是null(理论上不会出现) if (bestScoreIndex == -1) return 0; scores.asMap().forEach((index, score) { // 仅处理有效分数,且确保当前最佳分数非null if (score != null && scores[bestScoreIndex] != null) { final currentBest = scores[bestScoreIndex]!; if (score > currentBest || (score == currentBest && _random.nextBool())) { bestScoreIndex = index; } } }); return bestScoreIndex; }
关键修复点说明
- 分数初始化:在处理有效列时,先检查并初始化
scores[i]为0.0,避免后续运算符操作时遇到null - 非空断言
!:在执行+=/-=时,利用逻辑判断(target != -1且已初始化)确保scores[i]非null,用!明确告知编译器此处变量不可能为null - 分数比较逻辑:在
_getBestScoreIndex中,增加对scores[bestScoreIndex]的非空判断,仅对两个非null分数进行大小比较,避免空安全报错
内容的提问来源于stack exchange,提问作者Nitneuq
相关产品推荐
相关产品推荐

