将Kotlinx中的2d数组反序列化

时间:2020-11-04 15:46:49

标签: json kotlin multidimensional-array serialization

我对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,但它只是数组的一级。

感谢您的帮助:)

1 个答案:

答案 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 } })
}