我对Kotlin还是很陌生,但是我已经成功地在许多情况下使用过Kotlin序列化-即使对于嵌套类,mutableLists等也可以直接使用。但是我在二维数组方面苦苦挣扎。
我的课:
import kotlinx.serialization.*
@Serializable
data class Thing(val name:String)
@Serializable
data class Array2D(val width:Int, val height:Int,
var arrayContents:Array<Array<Thing?>> = Array(1){Array(1){null} }){
init{
arrayContents = Array(width){Array(height){null} }
}
}
在执行此操作时:
val a = Array2D(2, 2)
a.arrayContents[0][0] = Thing("T0")
a.arrayContents[0][1] = Thing("T1")
a.arrayContents[1][0] = Thing("T2")
a.arrayContents[1][1] = Thing("T3")
val json = Json {
allowStructuredMapKeys = true
}
val jsonString = json.encodeToString(Array2D.serializer(), a)
assertEquals(
"""
{"width":2,"height":2,"arrayContents":[[{"name":"T0"},{"name":"T1"}],[{"name":"T2"},{"name":"T3"}]]}
""".trim(),
jsonString
) // encoding is OK
val b = json.decodeFromString(deserializer = Array2D.serializer(), jsonString)
// this fails to reproduce "a" and stops at first array level
// b.arrayContents = {Thing[2][]} (array of nulls) instead of {Thing[2][2]} (array of array of Thing)
如果可以将类编码为String,也应该对其进行解码,对吧?还是我在这里想念什么?也许我应该使用自定义序列化程序,但是没有多少例子适合我的情况。一个示例是https://github.com/Kotlin/kotlinx.serialization/issues/357,但它只是数组的一级。
感谢您的帮助:)
答案 0 :(得分:0)
数组(包括多维)的序列化/反序列化是开箱即用的。
意外行为与数据类的init
部分有关。在反序列化发生后执行,并覆盖从JSON解析的数据。
当您手动创建Array2D
的实例时也会发生这种情况:
val x = Array2D(1, 1, Array(1) { Array(1) { Thing("0") } })
println(x.arrayContents[0][0]) //will print null
您只需要用辅助构造函数替换init
块(顺便说一下,arrayContents
的默认值是多余的),您现在可以将arrayContents
声明为val
:
@Serializable
data class Array2D(val width: Int, val height: Int, val arrayContents: Array<Array<Thing?>>) {
constructor(width: Int, height: Int) : this(width, height, Array(width) { Array(height) { null } })
}