在 Kotlin 中创建表示嵌套 xml 的 class 的最佳方法是什么
what's best way to create a class representing nested xml in Kotlin
考虑以下 xml 文件
<Dataset>
<Table1>
<colA>AAA</colA>
<colB>BBB</colB>
</Table1>
<Table1>
<colA>aa</colA>
<colB>bb</colB>
</Table1>
<Table2>
<colX>xxx</colX>
</Table1>
</Dataset>
构造一个 class 以保存该文件中的记录的最佳方法是什么(使用外部 class 的 ArrayList)?
我试过使用内部 classes,像这样:
class Dataset {
inner class Table1 {
var colA:String = ""
var colB:String = ""
}
inner class Table2 {
var colX:String = "x"
}
}
问题是 - 当我创建数据集 class 的实例时,我无法在其中设置内部 classes 的属性,即使我可以读取它们(是因为它们没有实例化?)
换句话说,下面代码的输出是 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 中实例化内部 classes 时设置属性 class:
class Dataset {
val table1 = Table1()
val table2 = Table2()
inner class Table1 {
...
但正如我之前提到的,我使用 ArrayList
追加记录
这意味着(如果我理解正确的话),当我为 Table1 条目创建数据集然后将其附加到 ArrayList 时,我仍然在该数据集中实例化了 dataset.table2,即使它没有被使用
我也可以像这样实例化内部 classes:
table1 = Dataset().Table1()
只要我可以将它们添加到现有的数据集实例中
val dataset = Dataset()
dataset.Table1() = table1 //this bit doesn't work for me :(
总结一下:
1) 关于如何更好地构建数据集的任何想法 class?
2) 如果不是,如何在其外部 class 实例中设置内部 class 的属性?
您对 Table1 和 Table2 的定义只不过是 class 定义,所以是的,您需要参数来表示它们的实例。问题不仅在于它们没有被实例化,而且根本没有它们的属性。
您在需要其他 class 之一时实例化外部 class 副本的想法没有意义。编译器要求您这样做的唯一原因是您在那些 class 定义中使用了关键字 inner
。由于它们与 Dataset 没有共享引用,因此它们不需要 inner
.
inner
的意思是class只能存在于外class的上下文中。 inner
class 的好处是它可以直接引用外部 class 的属性,并且您始终知道内部 class 的任何实例都内在地链接到特定的外部 class 的实例。对于像这样的简单层次结构,您不需要任何这些内部 class 功能。
你需要这样的东西:
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)
由于您的表格是可选的,因此它们必须可以为空,并且空值表示它是空白的。
在 class 定义中使用 data
让 Kotlin 为您生成 toString
、hashcode
和 equals
。
您的示例 XML 在数据集中显示了多个 Table1,因此您可能需要将 DataSet 的参数更改为集合,以便能够容纳每种类型的多个表:
data class DataSet (val table1s: MutableList<Table1> = mutableListOf(),
val table2s: MutableList<Table2> = mutableListOf())
编辑:
如果您确实需要这些是内部 classes,则必须具有内部 classes 实例的属性。并且您必须始终在实例的上下文中实例化它们 "own" 它。
// 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()
考虑以下 xml 文件
<Dataset>
<Table1>
<colA>AAA</colA>
<colB>BBB</colB>
</Table1>
<Table1>
<colA>aa</colA>
<colB>bb</colB>
</Table1>
<Table2>
<colX>xxx</colX>
</Table1>
</Dataset>
构造一个 class 以保存该文件中的记录的最佳方法是什么(使用外部 class 的 ArrayList)?
我试过使用内部 classes,像这样:
class Dataset {
inner class Table1 {
var colA:String = ""
var colB:String = ""
}
inner class Table2 {
var colX:String = "x"
}
}
问题是 - 当我创建数据集 class 的实例时,我无法在其中设置内部 classes 的属性,即使我可以读取它们(是因为它们没有实例化?) 换句话说,下面代码的输出是 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 中实例化内部 classes 时设置属性 class:
class Dataset {
val table1 = Table1()
val table2 = Table2()
inner class Table1 {
...
但正如我之前提到的,我使用 ArrayList
这意味着(如果我理解正确的话),当我为 Table1 条目创建数据集然后将其附加到 ArrayList 时,我仍然在该数据集中实例化了 dataset.table2,即使它没有被使用
我也可以像这样实例化内部 classes:
table1 = Dataset().Table1()
只要我可以将它们添加到现有的数据集实例中
val dataset = Dataset()
dataset.Table1() = table1 //this bit doesn't work for me :(
总结一下:
1) 关于如何更好地构建数据集的任何想法 class?
2) 如果不是,如何在其外部 class 实例中设置内部 class 的属性?
您对 Table1 和 Table2 的定义只不过是 class 定义,所以是的,您需要参数来表示它们的实例。问题不仅在于它们没有被实例化,而且根本没有它们的属性。
您在需要其他 class 之一时实例化外部 class 副本的想法没有意义。编译器要求您这样做的唯一原因是您在那些 class 定义中使用了关键字 inner
。由于它们与 Dataset 没有共享引用,因此它们不需要 inner
.
inner
的意思是class只能存在于外class的上下文中。 inner
class 的好处是它可以直接引用外部 class 的属性,并且您始终知道内部 class 的任何实例都内在地链接到特定的外部 class 的实例。对于像这样的简单层次结构,您不需要任何这些内部 class 功能。
你需要这样的东西:
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)
由于您的表格是可选的,因此它们必须可以为空,并且空值表示它是空白的。
在 class 定义中使用 data
让 Kotlin 为您生成 toString
、hashcode
和 equals
。
您的示例 XML 在数据集中显示了多个 Table1,因此您可能需要将 DataSet 的参数更改为集合,以便能够容纳每种类型的多个表:
data class DataSet (val table1s: MutableList<Table1> = mutableListOf(),
val table2s: MutableList<Table2> = mutableListOf())
编辑: 如果您确实需要这些是内部 classes,则必须具有内部 classes 实例的属性。并且您必须始终在实例的上下文中实例化它们 "own" 它。
// 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()