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可空的空安全场景。
修复步骤
- 强类型声明列表变量,禁止使用弱类型
List、dynamic接收反序列化结果:// 正确声明,根据业务场景初始化即可 List<TimelineJson> timelinelist = welcomeFromJson(待解析的json字符串); - 修正排序逻辑,使用正确的属性访问方式,调整为降序排列,补充空值兼容:
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
相关产品推荐
相关产品推荐

