【发布时间】:2021-02-17 12:49:37
【问题描述】:
我正在尝试编写序列化函数,以便能够序列化 Kotlin 中的任何向量 (=ArrayList),以及扩展具有 toBinary() 函数的 Serialize 类的原始类型和类。
我还有一个自定义的 WriteDataStream 类(下面的代码)来序列化具有正确格式、字节序等的字段。
我是 Kotlin 的新手,但有 C++ 方面的经验。在 C++ 中,我使用模板和模板专业化来轻松解决这个问题,但在使用 Kotlin 时,我已经苦苦挣扎了几天,但没有成功。
我有一个自定义矢量类MyVector,它扩展了ArrayList 并增加了一个最大尺寸。我想用任何泛型类型T 序列化它,包括像MyVector<MyVector<MyClass>> 这样的内部向量。
我的WriteDataStream 包含以下内容:
inline fun <reified T> write(vector: MyVector<T>) {
this.writeSize(vector.size.toULong(), vector.MAX_SIZE)
for (element in vector) {
write<T>(element)
}
}
inline fun <reified T: Serialize> write(value: T) {
writeSerialize(value as Serialize)
}
inline fun <reified T> write(value: T) {
when (T::class) {
UByte::class -> {
writeUInt8(value as UByte)
}
UShort::class -> {
writeUInt16(value as UShort)
}
UInt::class -> {
writeUInt32(value as UInt)
}
ULong::class -> {
writeUInt64(value as ULong)
}
Byte::class -> {
writeInt8(value as Byte)
}
Short::class -> {
writeInt16(value as Short)
}
Int::class -> {
writeInt32(value as Int)
}
Long::class -> {
writeInt64(value as Long)
}
Boolean::class -> {
writeBoolean(value as Boolean)
}
Float::class -> {
writeFloat(value as Float)
}
Double::class -> {
writeDouble(value as Double)
}
else -> {
error("Default serialization:" + T::class.qualifiedName)
}
}
}
所有底层函数 writeXXX() 都经过测试并且工作正常。但是,当使用扩展 Serialize 的类来序列化 MyVector 时,我属于“默认序列化”的情况:
@Test
fun writeVectorOfStructure() {
class TestStructure: Serialize() {
override fun toBinary(stream: WriteDataStream) {
stream.writeUInt32(17U)
stream.writeUInt8(3U)
stream.writeDouble(555.555)
}
}
val value = MyVector<TestStructure>(MAX_SIZE, arrayListOf(TestStructure(), TestStructure()))
writeStream.write(value)
val bytes: UByteArray = writeStream.byteArray()
Assert.assertEquals(bytes.size, 28) // = 2 (for size) + 2*(4+1+8) = 28 bytes
}
所以我的问题是:为什么 Kotlin 不使用该功能
inline fun <reified T: Serialize> write(value: T)
当它使用通用的T = Serialize 序列化向量的元素 (write<T>(element)),而是使用更通用的元素时?
inline fun <reified T> write(value: T)
在 C++ 中,编译器总是使用最适合的函数。
有没有办法克服 Kotlin 中的这个限制?
我尝试过使用和不使用具体类型,我也尝试过非泛型函数:inline fun write(value: Serialize),但没有成功。唯一可行的方法是在完全通用的inline fun <reified T> write(value: T) 中为“Serialize”类的“实例”添加一个案例,但这并不是一个很好的解决方案。
谢谢!
【问题讨论】:
标签: kotlin serialization