Kotlin enum val 返回 null,尽管它是在编译时设置的

Kotlin enum val is returning null, despite being set at compile time

我有一个包含多个字段的 Kotlin 枚举。其中一个字段 (enterableBoard) 是另一个枚举的值。在运行时,尽管已设置此 val,但它仍为 null。

我以前从未见过这样的东西,其他字段工作正常,甚至是引用当前 Item 的字段!我已经包括了完整的枚举定义,因为我不确定什么是相关的。

Item 枚举和一个值,其中 enterableBoard 意外为空而不是 Board.SPACEX_EARLY_TREES

enum class Item(
    val chain: ItemChain,
    val tier: Int,
    @StringRes val title: Int,
    @DrawableRes val image: Int,
    val generatorMaxEnergy: Int = 0, 
    val enterableBoard: Board? = null,
    val mergeBonus: Pair<Item, Int>? = null, 
    val redeemable: Pair<InfoLong, Int>? = null
) {
    TREE_9(ItemChain.TREE, 9, R.string.item_tree9, R.drawable.item_tree9,
        generatorMaxEnergy = 50, enterableBoard = Board.SPACEX_EARLY_TREES)
}

Board枚举和相关值:

enum class Board(
    val campaign: Campaign,
    @StringRes val title: Int,
    @StringRes val description: Int,
    @DrawableRes val background: Int,
    @DrawableRes val image: Int,
    val unlockCost: Int,
    val template: List<Item>
) {
    SPACEX_EARLY_TREES(Campaign.SPACEX_EARLY, R.string.board_spacex_early_tree_title, R.string.board_spacex_early_tree_description,
        R.drawable.background5, R.drawable.background5, 0,
        listOf(Item.FRUITVEG_1, Item.FRUITVEG_2, Item.FRUITVEG_1))
}

这是 enterableBoard 意外为空的屏幕截图:

补充说明:

我很确定这是因为您有相互参考。 Board 在其构造函数中引用 Item,反之亦然。两个枚举 类' 成员中的一个在另一个之前实例化,因此对其他值的引用在引用它们时仍然为空。这是一种偷偷摸摸的方法,你可以通过做一些你不应该做的事情,比如调用来自构造函数的 open 函数。

基本上,枚举不能安全地相互引用,因为它们在实例化时的编译和行为方式。编译器是否应该针对这种情况显示警告或错误?可能吧,但显然不是。

这是问题的最小可重现示例:

enum class Item (val board: Board) {
    X(Board.Y)
}

enum class Board(val item: Item) {
    Y(Item.X)
}

fun main() {
    Item.X
    println(Board.Y.item)
}

打印null是因为引用Item.X导致Item的成员先被尝试实例化,但是由于它的构造函数引用了Board,所以Board实际上是先实例化的,并且使用仍然为null的Item.X参考。