如何使用 kotlinx 序列化使用 open val 序列化 kotlin 密封类

Posted

技术标签:

【中文标题】如何使用 kotlinx 序列化使用 open val 序列化 kotlin 密封类【英文标题】:How to serialize kotlin sealed class with open val using kotlinx serialization 【发布时间】:2020-11-20 04:38:46 【问题描述】:
import kotlinx.serialization.Serializable

@Serializable
sealed class Exercise(open val id: String) 

    @Serializable
    data class Theory(override val id: String) : Exercise(id)

我的代码中有这样的密封类,编译器告诉我: Serializable class has duplicate serial name of property 'id', either in the class itself or its supertypes.

有没有办法在可序列化的密封类中打开 val,在覆盖它时可以正常工作?

【问题讨论】:

你试过了吗:data class Theory(id: String):Exercise(id) 我不能用数据类这样做(因为构造函数必须只有属性(val / var)参数),但即使我用class Theory(id: String) : Exercise(id)代替,我也有这个错误:@ 987654325@ 【参考方案1】:

这是Kotlin issue KT-38958。这似乎是Constructor properties requirement 的一个极端案例。

可以通过下面的实现来解决,

import kotlinx.serialization.*
import kotlinx.serialization.json.Json

@Serializable
sealed class Exercise 
    abstract val id: String

    @Serializable
    data class Theory(override val id: String) : Exercise()


fun main() 
    val t1 = Exercise.Theory("t1")
    val t1Json = Json.encodeToString(t1)
    println(t1Json)
    println(Json.decodeFromString<Exercise.Theory>(t1Json).toString())

将输出:

"id":"t1"
Theory(id=t1)

有关详细信息,请参阅 Kotlin 序列化指南中的 "Designing serializable hierarchy"。

【讨论】:

在我的情况下,由于某种原因,我无法将 val 声明为 abstract 有一个声明为abstract(或sealed,是abstract的特殊形式)的类? 啊,不,我意识到我在主构造函数而不是类主体中声明它是抽象的。我犯的典型 Kotlin 错误:D

以上是关于如何使用 kotlinx 序列化使用 open val 序列化 kotlin 密封类的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 kotlinx 序列化将值数组反序列化为集合

如何使用 kotlinx 序列化 json 的动态键

如何使用 kotlinx.serialization 将库类序列化为 Protobuf?

使用 kotlinx 序列化序列化选项列表

如何使用 kotlinx.serialization 在 Ktor 中序列化 Web Socket Frame.text

如何在 Kotlinx 序列化中序列化“任何”类型?