【问题标题】:How to control layout of polymorphic Kotlinx serialization?如何控制多态 Kotlinx 序列化的布局?
【发布时间】:2021-12-30 10:35:05
【问题描述】:

我有一个包含多态对象列表的 json,

{ 
  "someList": [
    { "type": "A", "value": {"aProp": false } },
    { "type": "B", "value": {"bProp": "1" } },
  ]
}

代表一个像这样的类型层次结构:

sealed class Base
class A(val aProp: Boolean): Base()
class B(val aProp: String): Base()

class BaseList(val someList: List<Base>)

我想把 JSON 反序列化成这样的类型,

但默认的 seales/polymorphic kotlinx 序列化程序会在对象本身中读取和写入鉴别器,如下所示:

{ 
  "someList": [
    { "type": "A", "aProp": false },
    { "type": "B", "bProp": "1" }
  ]
}

虽然我在对象本身之外得到了鉴别器。

如何将这样的 JSON 反序列化到这个 Kotlin 类型层次结构中?

【问题讨论】:

  • 你的意思是写class B(val bProp: String): Base()吗?
  • 第一个 JSON 对象是如何创建的?
  • @Diggi55 来自另一种语言和框架(快速序列化)

标签: kotlin kotlinx.serialization


【解决方案1】:

如果您不想编写自定义序列化程序,则必须匹配 JSON 的结构。您的原始 JSON 表示对象内的一个对象,因此您必须执行以下操作:

data class A(val value: AValue): Base()

data class AValue(val aProp: Boolean)

【讨论】:

  • 我认为polymorphic 序列化程序无论如何都会添加描述符。
  • 我不确定你的意思。 type 鉴别器将用于确定外部对象是A 还是B。如果需要,可以将其添加到数据类中:data class A(val type: String, val value: AValue): Base()
【解决方案2】:

好问题!让我非常恼火的是,JSON 中的多态性仍然没有标准。

我不认为在这里编写自定义序列化程序是一种可取的方法。您必须在整个代码库中应用自定义序列化程序。相反,您最好在序列化 JSON 的任何地方引入预处理和后处理步骤。从而拦截JSON并将其转换为kotlinx.serialization支持的格式。

Kotlinx 序列化还支持 JSON 配置中的“数组多态”,我个人更喜欢这种方式,但不太常见。它将类型存储在数组的第一个元素中,将值存储在第二个元素中。这似乎与您的目标格式相似。使用 JSON 转换器将所有 typevalue 对象转换为具有两个元素的数组应该是相当简单的。

Ps。我建议您将您的用例作为功能请求发布在 GitHub 上。维护者非常乐于接受反馈。这听起来像是某种类型的策略模式来处理不同格式的多态性。

【讨论】:

    猜你喜欢
    • 2020-09-15
    • 2020-02-15
    • 1970-01-01
    • 2020-03-09
    • 1970-01-01
    • 2020-12-05
    • 2021-02-24
    • 2021-05-14
    • 2018-04-01
    相关资源
    最近更新 更多