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

Dart JSON解析报错:参数类型'Id?'无法分配给参数类型'Id'如何解决

报错根因

  • Dart空安全机制下,idValues.map[json["id"]]、nameValues.map[json["name"]] 两个操作的返回值是可空类型Id?、Name?,触发场景包括:JSON对应字段本身为null、字段值不在你预定义的枚举映射表中
  • 但Source类的构造参数要求传入非空的Id、Name类型,类型不匹配触发编译错误
  • 额外注意:你现有代码还有两处隐含错误:Article类的author属性定义为非空String但fromJson方法里会返回null;EnumValues类中用late修饰的reverseMap判空逻辑不符合空安全规则,也需要同步修复

解决方案

方案1:允许枚举字段为空(适配接口字段可能为空的场景)

修改步骤:

  1. 修改Source类的属性和构造参数,调整为可空类型
  2. 修正EnumValues类的reverseMap定义,适配空安全规则
  3. 同步修正Article类的author等可能为空的属性定义

修改后的完整代码片段:

// 修正EnumValues类
class EnumValues<T> {
  Map<String, T> map;
  Map<T, String>? reverseMap; // 去掉late,改为可空类型

  EnumValues(this.map);

  Map<T, String> get reverse {
    reverseMap ??= map.map((k, v) => MapEntry(v, k));
    return reverseMap!;
  }
}

// 修正Source类
class Source {
  Source({
    this.id, // 去掉required,改为可空
    this.name, // 去掉required,改为可空
  });

  Id? id; // 改为可空类型
  Name? name; // 改为可空类型

  factory Source.fromJson(Map<String, dynamic> json) => Source(
        id: idValues.map[json["id"]],
        name: nameValues.map[json["name"]],
      );

  Map<String, dynamic> toJson() => {
        "id": idValues.reverse[id],
        "name": nameValues.reverse[name],
      };
}

// 修正Article类的可空字段
class Article {
  Article({
    required this.source,
    this.author, // 改为可空
    required this.title,
    required this.description,
    required this.url,
    required this.urlToImage,
    required this.publishedAt,
    required this.content,
  });

  Source source;
  String? author; // 改为可空类型
  String title;
  String description;
  String url;
  String urlToImage;
  DateTime publishedAt;
  String content;

  // 剩余fromJson、toJson代码无需调整
}

方案2:强制枚举字段非空(兜底默认值避免空值)

如果业务要求枚举字段不能为null,可以先给枚举新增unknown兜底值,解析时如果找不到对应值就返回兜底值:

修改步骤:

  1. 给Id、Name枚举新增unknown选项
  2. 解析时用??运算符指定默认兜底值
  3. 同步修正EnumValues、Article类的空安全问题

修改后的核心代码片段:

// 新增unknown枚举值
enum Id { THE_WALL_STREET_JOURNAL, unknown }
final idValues = EnumValues({
  "the-wall-street-journal": Id.THE_WALL_STREET_JOURNAL,
  "unknown": Id.unknown
});

enum Name { THE_WALL_STREET_JOURNAL, unknown }
final nameValues = EnumValues({
  "The Wall Street Journal": Name.THE_WALL_STREET_JOURNAL,
  "unknown": Name.unknown
});

// 修正Source的fromJson方法,指定默认值
factory Source.fromJson(Map<String, dynamic> json) => Source(
      id: idValues.map[json["id"]] ?? Id.unknown,
      name: nameValues.map[json["name"]] ?? Name.unknown,
    );

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 20:54:03