You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Dart中json解码后调用sort方法程序中断的原因及解决方法

问题触发原因
  • json.decode()的返回值是dynamic类型,编译期不会做类型校验:如果接口返回的JSON根结构不是数组(比如是单个对象、null、带业务包裹层的对象),运行时调用不存在的.sort()方法会直接抛出NoSuchMethodError,程序在该行中断。
  • 即使接口返回的是数组,如果数组内同时混杂多种类型值(比如字符串、数字、null、嵌套对象同时存在),compareNatural方法做值对比时会触发类型不匹配异常,导致执行中断。
  • compareNatural本身仅支持字符串、数字这类基础可比较类型的自然排序,如果数组元素是嵌套对象,没有指定具体排序字段的前提下,方法无法完成对象对比,会直接报错。
解决方法
  1. 先加类型校验,不要直接对dynamic类型的反序列化结果调用排序方法,参考实现:
response = await http.get(url);
if(response.statusCode == 200) {
  var dataJson = response.body;
  var decodeResult = json.decode(dataJson);

  // 先校验根结构是否为数组
  if (decodeResult is! List) {
    // 此处处理结构异常逻辑,比如打印错误日志、返回空结果
    print('接口返回结构不符合预期,根节点非数组类型');
    return;
  }
  // 显式转换为List类型,规避dynamic隐式错误
  List matchData = decodeResult;

  // 过滤数组内无法参与自然排序的无效值
  matchData = matchData.where((item) => item is String || item is num).toList();

  // 执行排序
  matchData.sort(compareNatural);
}
  1. 针对性排查调整:
  • 可以在sort调用外层加try-catch打印错误栈和运行时类型,快速定位根因:
    try {
      matchData.sort(compareNatural);
    } catch (e) {
      print('排序执行异常:$e');
      print('当前数据运行时类型:${matchData.runtimeType}');
    }
    
  • 如果数组元素是对象,需要按对象内指定字段排序,不要直接传compareNatural,自定义比较逻辑即可,比如按对象的title字段排序:
    matchData.sort((a, b) => compareNatural(a['title'], b['title']));
    
  • 如果数组内的数字以字符串格式存储,提前做统一类型转换,避免对比时出现类型不匹配问题。

内容的提问来源于stack exchange,提问作者장인수

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.31 10:27:09