在Kotlin中创建表示嵌套xml的类的最佳方法是什么

时间:2019-12-09 19:04:15

标签: kotlin inner-classes

考虑以下xml文件

<Dataset>
    <Table1>
        <colA>AAA</colA>
        <colB>BBB</colB>
    </Table1>
    <Table1>
        <colA>aa</colA>
        <colB>bb</colB>
    </Table1>
    <Table2>
        <colX>xxx</colX>
    </Table1>
</Dataset>

构造一个类来保存该文件中的记录的最佳方法是什么(使用外部类的ArrayList)?


我尝试使用内部类,例如:

class Dataset {
    inner class Table1 {
        var colA:String = ""
        var colB:String = ""
    }
    inner class Table2 {
        var colX:String = "x"
    }
}

问题是-当我创建Dataset类的实例时,即使我可以读取它们,也无法设置内部类的属性(是因为它们没有被实例化吗?) 换句话说,以下代码的输出是xx而不是xOK

val dataset = Dataset()
print("${dataset.Table2().colX}")    //returns x as in the class declaration
dataset.Table2().colX = "OK"
print("${dataset.Table2().colX}")    //returns x, but I want it to return OK

当我在外部类中实例化内部类时,可以设置属性:

class Dataset {
    val table1 = Table1()
    val table2 = Table2()
    inner class Table1 {
...

但是正如我之前提到的,我使用ArrayList

追加记录

这意味着(如果我正确理解的话),当我为一个Table1条目创建一个数据集然后将其追加到ArrayList时,即使未使用它,我仍然在该数据集中实例化了dataset.table2

我也可以像这样实例化内部类:

table1 = Dataset().Table1()

只要我可以将它们添加到现有的数据集实例中

val dataset = Dataset()
dataset.Table1() = table1    //this bit doesn't work for me :(

所以总结一下:

1)关于如何更好地构造数据集类的任何想法吗?

2)如果不是,如何在内部类的外部类实例中设置内部类的属性?

1 个答案:

答案 0 :(得分:1)

您对Table1和Table2的定义不过是类定义,因此,是的,您需要参数来表示它们的实例。问题不仅在于未实例化它们,而且根本没有用于它们的属性。

您需要在需要其他类之一时实例化外部类副本的想法没有任何意义。编译器要求您这样做的唯一原因是在这些类定义中使用了关键字inner。由于它们没有与数据集共享的引用,因此它们不必是inner

inner的含义是,该类只能存在于外部类的上下文中。 inner类的好处是它可以直接引用外部类的属性,并且您始终知道内部类的任何实例都固有地链接到外部类的特定实例。对于这样的简单层次结构,您不需要任何这些内部类功能。

您需要这样的东西:

data class Table1 (var colA: String = "", 
                   var colB: String = "")

data class Table2 (var colX: String = "")

data class DataSet (var table1: Table1? = null,
                    var table2: Table2? = null)

由于表是可选的,因此它们必须是可为空的,并且null值表示它为空。

在类定义中使用data会使Kotlin为您生成toStringhashcodeequals

您的示例XML在您的数据集中显示了多个Table1,因此您可能需要将DataSet的参数更改为collections才能容纳每种类型的多个表:

data class DataSet (val table1s: MutableList<Table1> = mutableListOf(),
                    val table2s: MutableList<Table2> = mutableListOf())

编辑: 如果实际上需要将它们作为内部类,则必须具有内部类实例的属性。而且,您必须始终在“拥有”它的实例的上下文中实例化它们。

// This works because the table was instantiated from the dataset that will reference it.
val dataset = DataSet()
dataset.table1 = dataset.Table1() 

// This doesn't work because you can't assign the new DataSet's table to some 
// other DataSet's property.
val dataset = DataSet()
dataset.table1 = DataSet().Table1()