如何将序列化程序设置为扩展公共接口的内部类



我正试图为Compose Desktop类创建一个使用kotlinx.serialization的序列化程序,我有这样的:

@Serializer(forClass = MutableState::class)
class MutableStateSerializer<T>(private val dataSerializer: KSerializer<T>) : KSerializer<MutableState<T>> {
override fun deserialize(decoder: Decoder) = mutableStateOf(decoder.decodeSerializableValue(dataSerializer))
override val descriptor: SerialDescriptor = dataSerializer.descriptor
override fun serialize(encoder: Encoder, value: MutableState<T>) = encoder.encodeSerializableValue(dataSerializer, value.value)
}

这应该用于MutableState类的实例(正如@Serializer注释所说(,但我必须为每个属性放置一个显式序列化程序,否则我会得到以下错误:

xception in thread "main" kotlinx.serialization.SerializationException: Class 'SnapshotMutableStateImpl' is not registered for polymorphic serialization in the scope of 'MutableState'.
Mark the base class as 'sealed' or register the serializer explicitly

使用的代码:

@Serializable
class Test {
var number = mutableStateOf(0)
}
fun main() {
val json = Json { prettyPrint = true }
val serialized = json.encodeToString(Test())
println(serialized)
}

我必须在我的财产上加上这个注释:

@Serializable(with = MutableStateSerializer::class)

难道没有一种方法可以自动将我的序列化程序链接到MutableState接口吗?由于SnapshotMutableStateImpl是内部的,我无法将其设置为此类。

您想要的目前是不可能的。其他人似乎请求了一个类似于你在GitHub上需要的功能:全局自定义序列化程序。

目前,对于第三方类,您需要通过以下三种方式之一指定序列化程序:

  • 将自定义序列化程序传递给encode/decode方法,以防将其序列化为根对象
  • 使用@Serializable在属性上指定序列化程序,就像您现在所做的那样
  • 使用@file:UseSerializers指定完整文件要使用的序列化程序

请注意,由于类型推断,number将被尝试序列化为mutableStateOf的返回类型。如果使用多态序列化将类型指定为接口(它有超类型吗?(,则可以尝试注册具体类型,并将具体类型的自定义序列化程序传递到那里。这并不是这个特性的真正目的,但我相信,如果您不想在多个地方指定序列化程序,它可能会起作用。但是,序列化的表单将在所有地方都包含一个类型鉴别器。

最新更新