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

Dart sort排序TimelineJson列表报类型不匹配错误如何解决

问题现象

对存储TimelineJson对象的列表按过期日期做降序排列时,抛出如下类型错误:

Expected a value of type '((TimelineJson, TimelineJson) => int)?', but got one of type '(dynamic, dynamic) => dynamic'

列表可正常加载,仅执行排序逻辑时触发错误。
相关代码片段如下:
排序逻辑:

void downloadtimeline(String job) {
  timelinelist.sort((a, b) {
    var adate = a['downloadUrlExpiration'];
    var bdate = b['downloadUrlExpiration'];
    return adate.compareTo(bdate);
  });
}

TimelineJson实体类代码:

import 'dart:convert';

List<TimelineJson> welcomeFromJson(String str) => List<TimelineJson>.from(
    json.decode(str).map((x) => TimelineJson.fromJson(x)));

String welcomeToJson(List<TimelineJson> data) =>
    json.encode(List<dynamic>.from(data.map((x) => x.toJson())));

class TimelineJson {
  TimelineJson({
    this.requestId,
    this.job,
    this.customer,
    this.requested,
    this.processed,
    this.downloadUrl,
    this.downloadUrlExpiration,
  });

  int? requestId;
  String? job;
  String? customer;
  DateTime? requested;
  DateTime? processed;
  String? downloadUrl;
  DateTime? downloadUrlExpiration;

  factory TimelineJson.fromJson(Map<String, dynamic> json) => TimelineJson(
    requestId: json["request_id"],
    job: json["job"],
    customer: json["customer"],
    requested: DateTime.parse(json["requested"]),
    processed: DateTime.parse(json["processed"]),
    downloadUrl: json["download_url"],
    downloadUrlExpiration: DateTime.parse(json["download_url_expiration"]),
  );

  Map<String, dynamic> toJson() => {
    "request_id": requestId,
    "job": job,
    "customer": customer,
    "requested": requested?.toIso8601String(),
    "processed": processed?.toIso8601String(),
    "download_url": downloadUrl,
    "download_url_expiration": downloadUrlExpiration?.toIso8601String(),
  };
}
故障原因
  • 变量timelinelist没有显式声明为List<TimelineJson>强类型,Dart类型推断失效,导致传入sort方法的比较函数被识别为(dynamic, dynamic) => dynamic签名,和sort方法要求的(TimelineJson, TimelineJson) => int类型不匹配。
  • 排序逻辑中错误使用Map的方括号[]语法访问类属性,TimelineJson是自定义类,需要用.运算符访问属性。
  • 现有比较逻辑默认是升序排列,不符合降序需求,且未处理downloadUrlExpiration可空的空安全场景。
修复步骤
  1. 强类型声明列表变量,禁止使用弱类型List、dynamic接收反序列化结果:
    // 正确声明,根据业务场景初始化即可
    List<TimelineJson> timelinelist = welcomeFromJson(待解析的json字符串);
    
  2. 修正排序逻辑,使用正确的属性访问方式,调整为降序排列,补充空值兼容:
    void downloadtimeline(String job) {
      timelinelist.sort((a, b) {
        // 空值处理:过期时间为null的项统一排到列表末尾
        if (a.downloadUrlExpiration == null) return 1;
        if (b.downloadUrlExpiration == null) return -1;
        // b.compareTo(a) 直接实现日期降序:过期时间越晚的项排在越前面
        return b.downloadUrlExpiration!.compareTo(a.downloadUrlExpiration!);
      });
      // 其余原有业务逻辑保持不变
    }
    

如果可以100%保证列表中所有项的downloadUrlExpiration都不为空,排序逻辑可以简化为:

timelinelist.sort((a, b) => b.downloadUrlExpiration.compareTo(a.downloadUrlExpiration));

内容的提问来源于stack exchange,提问作者Aiden P

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 20:45:51