3

不确定是否有可能,但对于我的一生,我无法弄清楚如何序列化它。

sealed class ServiceResult<out T : Any> {
    data class Success<out T : Any>(val data: T) : ServiceResult<T>()
    data class Error(val exception: Exception) : ServiceResult<Nothing>()
}

T 中的所有内容都使用@Serializable ex:

@Serializable
data class GalleryDTO(
    override val id: Int,
    override val dateCreated: Long,
    override val dateUpdated: Long,
    val name:String,
    val description:String,
    val photos:List<DTOMin>
) : DTO 
4

1 回答 1

0

在这种情况下,多态序列化将是一团糟(您必须手动注册作为泛型参数传递给的所有可能类型ServiceResult<T>),并且会有一些限制(不可能将原始类型(包括NothingString)注册为泛型参数,实例)。如果您只需要序列化(又名编码),我建议独立序列化两种子类型(为方便起见,将子类型确定包装到辅助函数中):

inline fun <reified T : Any> serializeServiceResult(x: ServiceResult<T>) = when (x) {
    is ServiceResult.Success -> Json.encodeToString(x)
    is ServiceResult.Error -> Json.encodeToString(x)
}

要序列化ServiceResult.Success,您只需用@Serializable注释标记它。这里棘手的部分是序列化ServiceResult.Error,或者更准确地说,是其exception: Exception字段的序列化。我建议只序列化它的消息(通过surrogate):

sealed class ServiceResult<out T : Any> {
    @Serializable
    data class Success<out T : Any>(val data: T) : ServiceResult<T>()

    @Serializable(with = ErrorSerializer::class)
    data class Error(val exception: Exception) : ServiceResult<Nothing>()
}

@Serializable
private data class ErrorSurrogate(val error: String)

class ErrorSerializer : KSerializer<ServiceResult.Error> {
    override val descriptor: SerialDescriptor = ErrorSurrogate.serializer().descriptor

    override fun deserialize(decoder: Decoder): ServiceResult.Error {
        val surrogate = decoder.decodeSerializableValue(ErrorSurrogate.serializer())
        return ServiceResult.Error(Exception(surrogate.error))
    }

    override fun serialize(encoder: Encoder, value: ServiceResult.Error) {
        val surrogate = ErrorSurrogate(value.exception.toString())
        encoder.encodeSerializableValue(ErrorSurrogate.serializer(), surrogate)
    }
}
于 2020-11-18T16:05:46.073 回答