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

无法将服务端响应转为Model类,Dart代码报错求解决

问题分析与解决:type List<dynamic> is not a subtype of type List<Person>

你的问题核心在于泛型类PersonResponse的fromJSON方法没有正确将List<dynamic>中的每个元素转换为指定的泛型类型T。Dart的json.decode返回的是动态类型,当你直接把json["person"](本质是List<dynamic>)赋值给List<T> persons时,Dart无法自动把列表里的每个Map对象转换成Person实例——因为泛型在运行时会被类型擦除,PersonResponse并不知道如何把动态元素转成你想要的具体类型。

具体来说,你的PersonResponse.fromJSON只是直接赋值,完全没处理元素的类型转换,这就导致了类型不匹配的错误。

解决方案

我们需要给PersonResponse添加一个类型转换逻辑,把列表里的每个Map元素转换成对应的T实例,这里有两种实用的实现方式:

方式一:在fromJSON中传入转换函数

修改PersonResponse类,让它的构造函数接收一个转换函数,用来把单个Map转成T对象:

class PersonResponse<T> {
  List<T> persons;

  // 新增转换函数参数,负责将Map转为T
  PersonResponse.fromJSON(Map json, T Function(Map) convert) {
    // 遍历List<dynamic>,逐个转换为T后再转成List<T>
    this.persons = (json["person"] as List).map((item) => convert(item)).toList();
  }
}

然后在main函数中调用时,传入Person的构造函数作为转换逻辑:

void main() { 
  var strJson = """{ "person": [ {"name": "Mahendra", "age": 28}, {"name": "Test", "age": 25} ] }"""; 
  var data = json.decode(strJson); 
  print("json: $data"); 
  // 传入Person.fromJSON作为转换函数
  var result = PersonResponse<Person>.fromJSON(data, (map) => Person.fromJSON(map)); 
  print("result: ${result.persons}"); 
}

方式二:让Model类实现通用解析接口(更优雅)

定义一个抽象接口,让所有需要解析的Model类都实现它,这样PersonResponse可以更通用,不用每次都传转换函数:

// 定义抽象解析接口
abstract class JsonParsable {
  factory JsonParsable.fromJson(Map json) => throw UnimplementedError();
}

// 让Person实现该接口
class Person implements JsonParsable { 
  String name; 
  int age; 

  Person.fromJSON(Map json) { 
    this.name = json["name"]; 
    this.age = json["age"]; 
  } 

  // 实现接口的factory构造函数
  factory Person.fromJson(Map json) => Person.fromJSON(json);
} 

// 约束T必须是JsonParsable的子类
class PersonResponse<T extends JsonParsable> { 
  List<T> persons; 

  PersonResponse.fromJSON(Map json) { 
    // 利用接口的fromJson方法批量转换元素
    this.persons = (json["person"] as List).map((item) => T.fromJson(item as Map)).toList(); 
  } 
}

此时main函数的调用会更简洁:

void main() { 
  var strJson = """{ "person": [ {"name": "Mahendra", "age": 28}, {"name": "Test", "age": 25} ] }"""; 
  var data = json.decode(strJson); 
  print("json: $data"); 
  var result = PersonResponse<Person>.fromJSON(data); 
  print("result: ${result.persons}"); 
}

额外小建议

  • 建议把fromJSON改成fromJson(小写j),符合Dart官方的命名规范。
  • 如果你的项目中有大量Model需要解析,推荐使用json_serializable包自动生成解析代码,避免手动写逻辑出错,效率也更高。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 08:57:47