Dart中含自定义类与函数的Map无法正常工作问题排查
问题原因与解决方案
问题出在自定义类作为Map键时的相等性判断逻辑。Dart中默认情况下,自定义类的实例是通过对象的内存地址(身份)来判定相等的——哪怕两个MalSymbol实例的value都是"+",它们也是完全独立的对象,因此Map无法将你创建的symbol和初始化时的MalSymbol('+')视为同一个键,最终返回null。而String作为内置类型,已经重写了相等性判断逻辑,所以fruits能正常查询。
解决方法:重写==运算符和hashCode
要让MalSymbol作为Map键正常工作,必须在类中重写==运算符和hashCode方法,让两个实例在value相同时被判定为相等:
class MalInt { final int value; MalInt(this.value); } class MalSymbol { final String value; MalSymbol(this.value); // 重写相等性判断逻辑 @override bool operator ==(Object other) { return other is MalSymbol && other.value == value; } // 基于value计算hashCode,保证相等实例的hashCode一致 @override int get hashCode => value.hashCode; } Map<MalSymbol, Function> repl_env = <MalSymbol, Function>{ MalSymbol('+'): (MalInt a, MalInt b) => MalInt(a.value + b.value), MalSymbol('-'): (MalInt a, MalInt b) => MalInt(a.value - b.value), MalSymbol('*'): (MalInt a, MalInt b) => MalInt(a.value * b.value), MalSymbol('/'): (MalInt a, MalInt b) => MalInt(a.value ~/ b.value), }; Map<String, int> fruits = <String, int>{"apple": 1, "banana": 2}; main() { var symbol = MalSymbol("+"); print(repl_env[symbol]); // 现在会输出对应的函数闭包 print(fruits["banana"]); // 2 }
验证结果
修改后运行代码,repl_env[symbol]会输出类似Closure: (MalInt, MalInt) => MalInt的内容,说明键匹配成功。
内容的提问来源于stack exchange,提问作者Flux Capacitor
相关产品推荐
相关产品推荐

