假设我想创建一个密封类,其中填充了一些对象。然后我想创建所有这些对象的列表,所以我在同伴对象中创建列表:
fun main() {
println(Color.Blue)
println(Color.allColors)
}
sealed class Color {
object Red : Color();
object Blue : Color();
companion object {
val allColors = listOf(
Red,
Blue
)
}
}
但是,上面代码的问题是当调用
Color.Blue
第一次直接初始化伴生对象
Blue
因此结果列表包含
[Red, null]
. 这是双重问题,因为kotlin假设列表包含非空值。
我知道上面的例子很简单,我可以替换
sealed class
具有
enum
,但这只是一个简单的例子。在许多情况下,在枚举上使用密封类是有益的(例如,当需要向单个对象添加类型参数时)。
用最少的样板和分配对象来解决这个问题的最佳方法是什么?我想出了两个解决办法,但我都不喜欢:
懒惰
fun main() {
println(Color.Blue)
println(Color.allColors)
}
sealed class Color {
object Red : Color();
object Blue : Color();
companion object {
val allColors by lazy {
listOf(
Red,
Blue
)
}
}
}
上面的解决方案看起来很好,不会导致太多锅炉板,但它创建了一个额外的对象,该对象中的每个属性都将永远存在。我还需要在任何其他属性上重复lazy关键字。
将初始化移动到另一个对象中
fun main() {
println(Color.Blue)
println(Color.allColors)
}
sealed class Color {
object Red : Color();
object Blue : Color();
private object Initializer {
val allColors = listOf(
Red,
Blue
)
}
companion object {
val allColors: List<Color>
get() = Initializer.allColors
}
}
此方法的优点是只为伴生对象中的所有属性创建一个对象,但它创建了许多额外的样板文件。
有没有更好的方法来实现这个目标?
编辑:Kotlin Issue Tracker上有此案例的问题:
https://youtrack.jetbrains.com/issue/KT-8970