You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 16:10:29