Dart/Flutter 中的动态类型转换

Dynamic Type Casting in Dart/Flutter

提问人:BadgerHobbs 提问时间:2/16/2023 更新时间:11/14/2023 访问量:656

问:

我正在编写一个库来动态序列化/反序列化 Dart/Flutter 中的任何对象(在想法上类似于 Python 的 Pydantic)。但是,我发现无法实现最后一个组件,即动态类型转换。为了将类型从 JSON 转换为 JSON,例如 List 到 List(或类似),这是必需的。使用反射从对象中检索类型。

以下是所需的实现(尽管据我了解,这在 Dart 中是不可能的)。

Map<String, Type> dynamicTypes = {"key": int };

// Regular casting would be "1" as int
int value = "1" as dynamicTypes["key"];

是否有一些解决方法可以实现?或者我对此走到了死胡同(因此已经不存在其他动态序列化/反序列化包)。

颤振 飞镖 类型 铸造

评论


答:

2赞 BadgerHobbs 2/16/2023 #1

对这个问题进行更多研究,在 Dart 当前的实现中,这似乎是不可能的,因为官方文档中引用了运行时反射。

GitHub 上正在讨论对此和相关包 dart:mirrors 的支持,但到目前为止,尽管对此类功能有一些渴望,但极不可能实现。

因此,唯一的选项是:

  • 使用代码生成库生成方法。
  • 手动序列化/反序列化方法。
  • 将具有复杂类型(如列表和映射)的类实现为动态类,从而实现(尽管是有限的)自动序列化/反序列化。
0赞 Chuck Batson 2/16/2023 #2

您的问题没有具体说明究竟是如何构建的,或者它的密钥是如何派生的。因此,也许有一个我不清楚的细节。dynamicTypes

但是这样的事情呢?

class Caster<T> {
  final T Function(String) fromString;
  Caster(this.fromString);
}

void main() {
  Map<String, Caster> dynamicTypes = { "key": Caster<int>((s) => int.parse(s)) };
  int v = dynamicTypes['key']!.fromString('1');
  print(v);
}

或者,如果将值作为 a 而不是字符串:dynamic

class Caster<T> {
  T cast(dynamic value) => value as T;
}

void main() {
  Map<String, Caster> dynamicTypes = { "key": Caster<int>() };
  dynamic a = 1;
  int v = dynamicTypes['key']!.cast(a);
  print(v);
}

或者更简洁地说:

void main() {
  dynamic a = 1;
  int v = a;
  print(v);
}