Dart Map取值异常:字符串相等但仅原变量能取到对应值
你的问题看似矛盾,但核心原因大概率是从jsonDecode得到的id字符串,表面显示为"blank",但实际和字面量"blank"存在隐藏差异——尽管==返回true,但Map的键匹配逻辑出现了异常(或者你忽略了某些细节)。下面是具体分析和验证步骤:
关键验证步骤
先添加以下调试代码,直接定位真实差异:
// 打印每个字符的Unicode码点,对比id和字面量的差异 print('id的码点:${id.runes.toList()}'); print('"blank"的码点:${'blank'.runes.toList()}'); // 打印hashCode,确认是否一致 print('id的hashCode:${id.hashCode}'); print('"blank"的hashCode:${'blank'.hashCode}'); // 确认_tiles中键的实际类型 print('_tiles第一个键的类型:${_tiles.keys.first.runtimeType}');
可能的原因及对应解决
隐藏的不可见字符:
比如id字符串包含零宽空格(U+200B)、换行符、制表符或全角空格,这些字符在print时不会显示,但会导致字符串实际内容和字面量不同。如果是这种情况,你会看到两者的码点列表长度不同,或者某个码点不一致。
解决:对id做trim处理,或者过滤不可见字符:String id = (tileMap['id'] as String).trim(); // 或者更彻底的过滤所有空白字符: String id = (tileMap['id'] as String).replaceAll(RegExp(r'\s'), '');Unicode等效字符混淆:
比如id中的字母是西里尔字母(如а代替拉丁字母a),这类字符视觉上和拉丁字母一致,但Unicode码点不同。不过这种情况会导致id == 'blank'返回false,和你的输出矛盾,可能性较低。Map类型不匹配:
如果_tiles的声明不是Map<String, TileData>,而是Map<dynamic, TileData>,理论上不影响,但如果键的实际类型不是String(不过as String强制转换失败会直接抛异常,这种情况概率极低),也会导致匹配失败。通过打印键的类型可以快速验证。
额外说明
Dart中字符串的==是严格比较Unicode标量值,只要==返回true,两个字符串的hashCode必须一致,Map的containsKey也应该返回true。你的输出出现矛盾,说明一定存在你没看到的字符差异,通过打印码点可以直接定位问题。
内容的提问来源于stack exchange,提问作者Justin808

