开启空安全的Dart无法识别Map非空值报错如何解决
问题根源
Dart 对 Map 的下标访问运算符[]的返回值天生是可空类型(V?),因为运行时无法保证你访问的键一定存在于Map中。即使你上一行刚给对应键赋值,编译器也不会做跨语句的Map键存在性推导,因此仍然会判定值为可空的int?,无法直接执行自增操作。
你之前尝试空断言不生效,是因为没有将!正确作用在下标访问返回的可空值上。
解决方案
方案1:正确使用空断言
将报错行修改为以下写法,空断言!直接跟在下标访问结果后,明确告诉编译器该值一定非空:
retval[text[i]]!++;
等价的易读写法:
retval[text[i]] = retval[text[i]]! + 1;
方案2:使用Map内置update方法(更推荐,符合Dart地道编码规范)
可直接合并原来的赋值+自增两行代码,不需要额外做空判断,通过ifAbsent参数处理首次出现的字符:
Map<String,int> get_frequency(String text) { Map<String,int> retval = {}; for (int i = 0; i<text.length; ++i) { retval.update(text[i], (existingValue) => existingValue + 1, ifAbsent: () => 1); } return retval; }
方案3:用局部变量承接值
把Map中取出的值存入局部变量后,编译器可以跟踪到局部变量的非空状态,不会触发空安全报错:
for (int i = 0; i<text.length; ++i) { int current = retval[text[i]] ?? 0; current++; retval[text[i]] = current; }
内容的提问来源于stack exchange,提问作者noah abe
相关产品推荐
相关产品推荐

