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

如何在Dart中使用built_value正确反序列化顶级泛型ParentItem?

解决Dart built_value泛型ParentItem的反序列化问题

咱们先从你的代码里的第一个小问题说起:你定义的序列化器没有带上泛型参数,这会导致built_value无法正确识别泛型类型的序列化规则。先修正这一点:

abstract class ParentItem<T> implements Built<ParentItem<T>, ParentItemBuilder<T>> {
  // 修正序列化器为泛型版本
  static Serializer<ParentItem<T>> get serializer => _$parentItemSerializer;

  int get skip;
  int get limit;
  int get total;
  BuiltList<T> get items;

  ParentItem._();
  factory ParentItem([void Function(ParentItemBuilder<T>) updates]) = _$ParentItem<T>;
}

接下来,泛型反序列化的核心难点在于:Dart运行时会擦除泛型类型信息,所以你必须明确告诉built_value序列化器具体的T类型是什么,这就需要用到FullType类来指定泛型参数。

完整反序列化步骤

1. 准备Serializers实例

首先要确保你把ParentItem和泛型参数T对应的类型(如果是自定义的built_value类)都注册到Serializers中。假设你的T是一个自定义的User类(同样用built_value实现):

// 先定义User的built_value类(示例)
abstract class User implements Built<User, UserBuilder> {
  static Serializer<User> get serializer => _$userSerializer;
  
  String get id;
  String get name;

  User._();
  factory User([void Function(UserBuilder) updates]) = _$User;
}

// 构建包含所有序列化器的Serializers实例
final Serializers serializers = (Serializers().toBuilder()
      ..add(ParentItem.serializer)
      ..add(User.serializer)
      // 如果需要,手动添加泛型Builder的工厂(部分版本的built_value可能自动生成,保险起见加上)
      ..addBuilderFactory(
        FullType(ParentItem, [FullType(User)]),
        () => ParentItemBuilder<User>(),
      ))
    .build();

2. 执行反序列化操作

现在你就可以用deserializeWith方法,通过specifiedType参数明确泛型类型:

// 假设你有从API获取的JSON数据
final Map<String, dynamic> jsonData = {
  "skip": 0,
  "limit": 10,
  "total": 100,
  "items": [
    {"id": "1", "name": "Alice"},
    {"id": "2", "name": "Bob"}
  ]
};

// 反序列化ParentItem<User>
final ParentItem<User> parentItem = serializers.deserializeWith(
  ParentItem.serializer,
  jsonData,
  specifiedType: FullType(ParentItem, [FullType(User)]),
);

3. 处理基础类型泛型

如果你的T是String、int这类基础类型,步骤类似,只需要把FullType(User)换成对应的基础类型即可:

// 反序列化ParentItem<String>
final ParentItem<String> stringItem = serializers.deserializeWith(
  ParentItem.serializer,
  jsonData,
  specifiedType: FullType(ParentItem, [FullType(String)]),
);

常见坑点提醒

  • 不要忘记指定specifiedType:省略这个参数的话,built_value无法推断泛型类型,会抛出序列化错误。
  • 确保所有相关类型都注册到Serializers:如果T是自定义built_value类,一定要把它的序列化器也添加进去。
  • 序列化器必须带泛型:一开始你写的Serializer<ParentItem>会丢失泛型信息,必须改成Serializer<ParentItem<T>>。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 08:44:09