Dart中对Map值使用+=报'+'方法不能无条件调用怎么解决?
Dart单词统计代码空安全错误修复方案
问题复现
实现字符串单词统计、返回结果Map的代码如下:
class WordCount { Map<String, int> countWords(String s) { var out = <String, int>{}; var words = s.split(" "); for (var word in words) { if (out.containsKey(word)) { out[word] += 1; } else { out[word] = 1; } } return out; } }
编译时out[word] += 1;行触发空安全报错,错误信息中文含义为:
无法无条件调用方法'+',因为接收方可能为
null。
尝试添加条件调用(使用?.)或给目标添加空检查(!)。dart(unchecked_use_of_nullable_value)
报错原因
这是Dart空安全机制的正常限制:Map的下标运算符[]返回值默认可空,即便提前通过containsKey判断了键存在,Dart静态分析器也无法将两个逻辑的关联作为类型推断依据,仍然会认为out[word]可能为null,因此不允许直接调用+方法。
修复方案
方案1:添加空断言(改动最小)
因为已经提前判断过键一定存在、值不可能为null,直接在取值后加空断言运算符!即可:
class WordCount { Map<String, int> countWords(String s) { var out = <String, int>{}; var words = s.split(" "); for (var word in words) { if (out.containsKey(word)) { out[word]! += 1; } else { out[word] = 1; } } return out; } }
方案2:使用Map内置update方法(更优雅)
直接调用Map原生的update方法,内置存在/不存在的分支处理,可以省略if判断,代码更简洁:
class WordCount { Map<String, int> countWords(String s) { var out = <String, int>{}; var words = s.split(" "); for (var word in words) { out.update(word, (value) => value + 1, ifAbsent: () => 1); } return out; } }
方案3:空合并运算符简化写法
用空合并运算符??处理默认值,同样可以省略if分支:
class WordCount { Map<String, int> countWords(String s) { var out = <String, int>{}; var words = s.split(" "); for (var word in words) { out[word] = (out[word] ?? 0) + 1; } return out; } }
内容的提问来源于stack exchange,提问作者mick.io
相关产品推荐
相关产品推荐

