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

在Hive Box中保存对象列表时类型推断异常问题

解决Hive存储嵌套对象列表的类型推断异常问题

问题场景

需要存储一组嵌套了DestinationResults(Hive对象)列表的CorrectionDestination对象,类定义如下:

CorrectionDestination类

@freezed
class CorrectionDestination extends HiveObject with _$CorrectionDestination {
  CorrectionDestination._();

  @HiveType(typeId: 4)
  factory CorrectionDestination({
    @HiveField(0) required int stepId,
    @HiveField(1) required String stepTitle,
    @HiveField(2) required String stepType,
    @HiveField(3) required bool isCurrentStep,
    @HiveField(4) required int projectStepId,
    @HiveField(5)
    @JsonKey(defaultValue: [])
    required List<DestinationResults> results,
  }) = _CorrectionDestination;

  factory CorrectionDestination.fromJson(Map<String, dynamic> json) =>
      _$CorrectionDestinationFromJson(json);
}

DestinationResults类

@freezed
class DestinationResults extends HiveObject with _$DestinationResults {
  DestinationResults._();

  @HiveType(typeId: 5)
  factory DestinationResults({
    @HiveField(0) required int stepResultId,
    @HiveField(1) required String stepResultTitle,
  }) = _DestinationResults;

  factory DestinationResults.fromJson(Map<String, dynamic> json) =>
      _$DestinationResultsFromJson(json);
}

问题现象

尝试通过带泛型的方式打开Box时出现类型推断异常:

final box = await Hive.openBox<List<CorrectionDestination>>('correctionDestinations');

但去掉泛型打开Box后,能通过打印获取到对象,但无法获得正确的类型约束:

final box = await Hive.openBox('correctionDestinations');
final availableDestinations = box.get(inspectionId);
print(availableDestinations);

当前环境信息:

[✓] Flutter (Channel stable, 3.16.3, on macOS 14.2 23C64 darwin-arm64, locale en-UA)
    • Flutter version 3.16.3 on channel stable at /Users/lesha/fvm/versions/3.16.0
    • Upstream repository https://github.com/flutter/flutter.git
    • Framework revision b0366e0a3f (5 weeks ago), 2023-12-05 19:46:39 -0800
    • Engine revision 54a7145303
    • Dart version 3.2.3
    • DevTools version 2.28.4

解决方案

1. 手动转换类型(推荐)

Hive对泛型集合的类型推断支持有限,建议直接打开非泛型Box,在获取数据时手动完成类型转换:

final box = await Hive.openBox('correctionDestinations');
// 安全转换类型,处理空值
final List<CorrectionDestination>? availableDestinations = 
    box.get(inspectionId) as List<CorrectionDestination>?;

// 或添加空检查与类型校验
final data = box.get(inspectionId);
if (data != null && data is List) {
  final List<CorrectionDestination> destinations = data.cast<CorrectionDestination>();
  // 后续业务逻辑
}

2. 检查适配器注册顺序

确保两个类的适配器已在main函数中正确注册,嵌套类需优先注册:

void main() async {
  await Hive.initFlutter();
  // 先注册嵌套的DestinationResults适配器
  Hive.registerAdapter(DestinationResultsAdapter());
  // 再注册CorrectionDestination适配器
  Hive.registerAdapter(CorrectionDestinationAdapter());
  runApp(const MyApp());
}

若适配器生成异常,执行flutter pub run build_runner build重新生成代码。

3. 用包装类实现强类型(可选)

如果需要严格的强类型约束,可以创建一个包装类来存储列表:

@HiveType(typeId: 6)
class CorrectionDestinationList extends HiveObject {
  @HiveField(0)
  final List<CorrectionDestination> items;

  CorrectionDestinationList(this.items);
}

注册该类的适配器后,即可用泛型方式操作Box:

// 注册适配器
Hive.registerAdapter(CorrectionDestinationListAdapter());

// 打开Box并存储数据
final box = await Hive.openBox<CorrectionDestinationList>('correctionDestinations');
await box.put(inspectionId, CorrectionDestinationList(destinationsList));

// 获取数据
final listWrapper = box.get(inspectionId);
final List<CorrectionDestination> availableDestinations = listWrapper?.items ?? [];

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 10:51:29