Dart列表排序报错NoSuchMethodError,求原因分析与解决方案
Dart Map列表排序报错分析与解决
问题场景
用户尝试对包含Map对象的列表按'ranking'字段降序排序,代码如下:
void main() { final hand1 = { 'ranking': 1, }; final hand2 = { 'ranking': 2, }; final hand3 = { 'ranking': 1, }; List players = [hand1, hand2, hand3]; players.sort((a, b) => b.ranking.compareTo(a.ranking)); // Expected players to become // [hand2, hand1, hand3] }
运行后抛出错误:
Unhandled exception: NoSuchMethodError: Class '_InternalLinkedHashMap<String, int>' has no instance getter 'ranking'. Receiver: _LinkedHashMap len:1 Tried calling: ranking #0 Object.noSuchMethod (dart:core-patch/object_patch.dart:38:5) #1 main.<anonymous closure> (file:///Users/primetimetran/Desktop/projects/flutpoke/poker_class.dart:15:28) #2 Sort._insertionSort (dart:_internal/sort.dart:69:36) #3 Sort._doSort (dart:_internal/sort.dart:58:7) #4 Sort.sort (dart:_internal/sort.dart:33:5) #5 ListMixin.sort (dart:collection/list.dart:356:10) #6 main (file:///Users/primetimetran/Desktop/projects/flutpoke/poker_class.dart:15:11) #7 _delayEntrypointInvocation.<anonymous closure> (dart:isolate-patch/isolate_patch.dart:297:19) #8 _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:192:12)
报错原因
代码中b.ranking的写法错误——Dart的Map对象没有名为ranking的实例getter方法。.操作符用于访问对象的属性,而Map的键值对需要通过['键名']的方式获取,直接用.会被解析为访问Map类的成员,导致找不到方法报错。
解决方法
方案1:修正Map键值访问方式
将排序闭包中的.改为[],同时建议给列表加上类型标注(增强代码安全性),代码如下:
void main() { final hand1 = {'ranking': 1}; final hand2 = {'ranking': 2}; final hand3 = {'ranking': 1}; // 明确列表类型为Map<String, int> List<Map<String, int>> players = [hand1, hand2, hand3]; // 使用[]获取ranking值,非空断言!确保值存在(已知每个Map都有该键) players.sort((a, b) => b['ranking']!.compareTo(a['ranking']!)); print(players); // 输出 [{ranking: 2}, {ranking: 1}, {ranking: 1}] }
如果不确定所有Map都包含'ranking'键,可以用??设置默认值避免空错误,比如b['ranking'] ?? 0。
方案2:使用强类型类替代Map(推荐)
对于复杂数据结构,使用自定义类比Map更规范,能在编译阶段检查错误,代码可读性更高:
class PlayerHand { final int ranking; PlayerHand(this.ranking); // 可选:重写toString让输出更直观 @override String toString() => 'PlayerHand(ranking: $ranking)'; } void main() { final hand1 = PlayerHand(1); final hand2 = PlayerHand(2); final hand3 = PlayerHand(1); List<PlayerHand> players = [hand1, hand2, hand3]; // 此时可以正常使用.ranking访问属性 players.sort((a, b) => b.ranking.compareTo(a.ranking)); print(players); // 输出 [PlayerHand(ranking: 2), PlayerHand(ranking: 1), PlayerHand(ranking: 1)] }
内容的提问来源于stack exchange,提问作者PrimeTimeTran
相关产品推荐
相关产品推荐

