使用Proto Data Store序列化含PersistentList对象时出现序列化异常求助
Proto Data Store序列化PersistentList失败问题解决
问题背景
尝试使用Proto Data Store保存包含PersistentList的对象,已为数据类添加@Serializable注解,但仍触发序列化错误;由于需要实例化该类并传递给其他组件,无法将PersistentList基类设置为sealed。
相关代码
数据类定义
@Serializable @SerialName("SavedEvents") data class SavedEvents( val SavedEventsList: PersistentList<Event> = persistentListOf() ) @Serializable @SerialName("Event") data class Event( @Contextual val VEvent: VEvent )
序列化器实现
override suspend fun writeTo(t: SavedEvents, output: OutputStream) { val json = Json { useArrayPolymorphism = true } output.write( json.encodeToString( serializer = SavedEvents.serializer(), value = t ).encodeToByteArray() ) }
错误信息
kotlinx.serialization.SerializationException: Class 'SmallPersistentVector' is not registered for polymorphic serialization in the scope of 'PersistentList'. Mark the base class as 'sealed' or register the serializer explicitly.
解决方法
错误原因是kotlinx.serialization无法自动识别PersistentList的具体实现类(如SmallPersistentVector),以下两种方案可解决:
方案1:显式注册PersistentList多态序列化器
在Json配置中添加序列化模块,注册PersistentList的所有实现类:
import kotlinx.collections.immutable.SmallPersistentVector import kotlinx.serialization.modules.SerializersModule import kotlinx.serialization.modules.polymorphic import kotlinx.serialization.modules.subclass val persistentListModule = SerializersModule { polymorphic(PersistentList::class) { subclass(SmallPersistentVector::class, SmallPersistentVector.serializer()) // 若项目中用到其他PersistentList实现类(如PersistentVector),需一并注册 } } // 修改Json配置 val json = Json { useArrayPolymorphism = true serializersModule = persistentListModule }
注:需确保所有PersistentList实现类自带序列化支持(kotlinx.collections.immutable库中的类默认支持)。
方案2:转换为普通List序列化(推荐)
通过自定义序列化器或手动转换,将PersistentList转为普通List后再序列化,反序列化时转回PersistentList:
方法A:自定义序列化器
import kotlinx.collections.immutable.PersistentList import kotlinx.collections.immutable.toPersistentList import kotlinx.serialization.KSerializer import kotlinx.serialization.descriptors.SerialDescriptor import kotlinx.serialization.descriptors.listSerialDescriptor import kotlinx.serialization.encoding.Decoder import kotlinx.serialization.encoding.Encoder import kotlinx.serialization.serializer class PersistentListSerializer<T>(private val elementSerializer: KSerializer<T>) : KSerializer<PersistentList<T>> { override val descriptor: SerialDescriptor = listSerialDescriptor(elementSerializer.descriptor) override fun serialize(encoder: Encoder, value: PersistentList<T>) { encoder.encodeSerializableValue(serializer<List<T>>(), value.toList()) } override fun deserialize(decoder: Decoder): PersistentList<T> { val list = decoder.decodeSerializableValue(serializer<List<T>>()) return list.toPersistentList() } } // 修改SavedEvents类,指定序列化器 @Serializable @SerialName("SavedEvents") data class SavedEvents( @Serializable(with = PersistentListSerializer::class) val SavedEventsList: PersistentList<Event> = persistentListOf() )
方法B:序列化时手动转换
override suspend fun writeTo(t: SavedEvents, output: OutputStream) { val json = Json { useArrayPolymorphism = true } // 临时转换为普通List对象 val tempModel = t.copy(SavedEventsList = t.SavedEventsList.toList()) // 用List的序列化器处理 val serialized = json.encodeToString( SavedEvents.serializer().copy( savedEventsListSerializer = serializer<List<Event>>() ), tempModel ) output.write(serialized.encodeToByteArray()) } // 反序列化时同理,将List转回PersistentList
内容的提问来源于stack exchange,提问作者koda
相关产品推荐
相关产品推荐

