【问题标题】:What is the best way to serialize/deserialize Dart's new enum with JSON?用 JSON 序列化/反序列化 Dart 的新枚举的最佳方法是什么?
【发布时间】:2015-01-29 22:40:16
【问题描述】:

我想利用 Dart 的新(实验性)enum 功能而不是使用静态 const 字符串堆栈,但是使用 JSON 序列化/反序列化 enum 变量的最佳方法是什么?我已经让它以这种方式工作,但肯定有更好的解决方案:

enum Status {
  none,
  running,
  stopped,
  paused
}

Status status1 = Status.stopped;
Status status2 = Status.none;

String json = JSON.encode(status1.index);
print(json);   // prints 2

int index = JSON.decode(json);
status2 = Status.values[index];
print(status2);  // prints Status.stopped

如果您使用索引进行序列化,您可能会被锁定为使您的枚举永远保持相同的顺序,所以我更喜欢使用某种字符串形式。有人知道吗?

【问题讨论】:

  • 我认为您也需要枚举名称(如类型名称)。如果您没有枚举名称,您怎么知道要反序列化到哪种类型。您还应该意识到,为了持久性等目的而序列化/反序列化枚举并不是一个好主意。如果您在现有值之前的某处添加一个值,则给定名称的索引可能会更改并破坏序列化/反序列化,因为 Dart 枚举不允许分配自定义枚举值。
  • 是的,正是,冈特。正如我在问题中提到的那样,以这种方式使用索引似乎很脆弱,但我看不到另一种方式。我希望能够在客户端和服务器应用程序之间的通信中使用枚举,但除非其他人提出更多见解,否则我现在只能坚持使用字符串。
  • 如果您仅将它用于客户端/服务器并共享实现,我认为使用枚举很好。我发现解决方法(具有静态值的类)更灵活,而且创建起来也不太冗长,除了最简单的情况外,更喜欢枚举。
  • 枚举被设计为允许缩小,所以如果你想在浏览器中使用它们的名字作为字符串,这基本上归结为与使用缩小镜像相同的问题。我想说最好的方法是使用/构建一个序列化包,在开发时在服务器和 dartium 中可以使用镜像(甚至只是解析 toString 输出),但在构建时会自动为客户端生成序列化代码.
  • 2021 年!现在你可以使用扩展了! medium.com/flutter/enums-with-extensions-dart-460c42ea51f7

标签: json enums dart


【解决方案1】:

作为之前建议的答案之一,如果您在客户端和服务器上共享相同的实现,那么序列化名称是我认为最好的方法,并且尊重S.O.L.I.D design 中的打开/关闭原则,说明:

“软件实体(类、模块、函数等)应该对扩展开放,对修改关闭”

如果您需要向 Enum 添加另一个成员,则使用索引而不是名称会弄乱代码的所有逻辑。但是使用该名称将允许扩展。

底线,序列化你的枚举名称,为了正确反序列化它,编写一个小函数,将枚举作为字符串给出,迭代枚举的所有成员并返回适当的成员。如:

Status getStatusFromString(String statusAsString) {
  for (Status element in Status.values) {
     if (element.toString() == statusAsString) {
        return element;
     }
  }
  return null;
}

所以,要序列化:

Status status1 = Status.stopped;
String json = JSON.encode(status1.toString());
print(json) // prints {"Status.stopped"}

反序列化:

String statusAsString = JSON.decode(json);
Status deserializedStatus = getStatusFromString(statusAsString);
print(deserializedStatus) // prints Status.stopped

这是迄今为止我发现的最好的方法。希望这会有所帮助!

【讨论】:

  • 是的,不幸的是,这也是我所知道的最好的方法。到目前为止,它的不优雅和可能的性能影响使我根本无法使用枚举,也从不使用需要序列化的数据(大多数数据,对我来说,碰巧)。枚举实现是我不喜欢 Dart 的少数几个方面之一。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-24
  • 2017-04-10
  • 2020-06-29
  • 2013-09-01
  • 1970-01-01
相关资源
最近更新 更多