Dart Hive使用Set类型触发未知类型错误该如何解决?
报错原因
Hive默认仅内置支持int、String、bool、List、Map等基础类型的序列化,没有内置Set类型的适配器,因此直接写入Set实例时会抛出未知类型错误。
解决方案
方案1:转换为List存取(无需自定义适配,实现最简单)
存数据时将Set转为List,读取时再转回Set即可,修改后的代码如下:
final Box box = Hive.box("NumberBox"); // 存时转List box.put("uniqueIds", <int>{}.toList()); // 取时转Set var setList = (box.get("uniqueIds") as List<int>).toSet(); setList.add(1); setList.add(2); setList.add(3); // 更新后重新存入时再次转List box.put("uniqueIds", setList.toList());
该方案无需额外配置,适合Set使用频次低的场景。
方案2:自定义Set类型适配器(支持直接存取Set)
如果需要频繁操作Set,不想每次做类型转换,可以自己实现TypeAdapter,步骤如下:
- 定义对应类型的Set适配器,这里以
Set<int>为例:
class SetIntAdapter extends TypeAdapter<Set<int>> { // 保证typeId不与其他已注册适配器重复即可 @override final int typeId = 101; @override Set<int> read(BinaryReader reader) { int length = reader.readInt(); Set<int> result = <int>{}; for (int i = 0; i < length; i++) { result.add(reader.readInt()); } return result; } @override void write(BinaryWriter writer, Set<int> obj) { writer.writeInt(obj.length); for (int element in obj) { writer.writeInt(element); } } }
- 在Hive初始化后、打开Box前注册适配器:
Hive.init(你的存储路径); Hive.registerAdapter(SetIntAdapter()); // 再执行打开Box的操作
- 此时你原来的代码无需修改即可正常运行:
final Box box = Hive.box("NumberBox"); box.put("uniqueIds", <int>{}); var setList = box.get("uniqueIds") as Set<int>; setList.add(1); setList.add(2); setList.add(3);
如果需要支持其他元素类型的Set,修改适配器内的读写逻辑或者实现泛型适配器即可。
内容的提问来源于stack exchange,提问作者Printer
相关产品推荐
相关产品推荐

