【发布时间】:2021-06-07 18:19:51
【问题描述】:
我想在 Kotlin Multiplatform 项目中使用 kotlinx.serialization 解码包含多态类结构中对象列表的 json 字符串,但它仅适用于 JVM,不适用于 Native。这是一个最小的可重现示例:
@Serializable
abstract class Project {
abstract val name: String
}
@Serializable
@SerialName("BasicProject")
data class BasicProject(override val name: String): Project()
@Serializable
@SerialName("OwnedProject")
data class OwnedProject(override val name: String, val owner: String) : Project()
fun main() {
val data = Json.decodeFromString<List<Project>>("""
[
{"type":"BasicProject","name":"example"},
{"type":"OwnedProject","name":"kotlinx.serialization","owner":"kotlin"}
]
"""))
}
这适用于 JVM,但在 Native 上会引发以下异常:
kotlinx.serialization.SerializationException: Serializer for class ‘Project’ is not found.
Mark the class as @Serializable or provide the serializer explicitly.
On Kotlin/Native explicitly declared serializer should be used for interfaces and enums without @Serializable annotation.message
之前在编码的上下文中已经讨论过这个问题,并且已经提出了一些解决方法,例如here,但我的问题是解码。是否有解决方法,还是我只需实现自己的 json 解析器?
【问题讨论】:
-
实际上,如果没有为
Json明确指定serializersModule,即使在JVM 中也无法正常工作:val module = SerializersModule { polymorphic(Project::class) { subclass(BasicProject::class); subclass(OwnedProject::class) } }; val data = Json { serializersModule = module }.decodeFromString<List<Project>>(...) -
如果您指定上述
serializersModule并明确传递序列化程序,它将在 Kotlin/Native 中工作:object ListOfProjectSerializer : KSerializer<List<Project>> by ListSerializer(Project.serializer()); val data = Json { serializersModule = module }.decodeFromString(ListOfProjectSerializer, ...)吗? -
是的,非常感谢!如果您将其发布为答案,我会将其标记为已接受。
标签: json kotlin json-deserialization kotlin-native kotlinx.serialization