首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Kotlin enum val返回null,尽管在编译时设置。

Kotlin enum val返回null,尽管在编译时设置。
EN

Stack Overflow用户
提问于 2021-08-20 18:07:04
回答 1查看 1K关注 0票数 1

我有一个多字段的Kotlin枚举。其中一个字段(enterableBoard)是另一个枚举的值。在运行时,尽管设置了这个val,但它仍然是空的。

我以前从未见过这样的情况,其他字段也很好,甚至引用当前Item的字段也是如此!我已经包含了完整的枚举定义,因为我不确定什么是相关的。

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

代码语言:javascript
复制
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枚举和相关值:

代码语言:javascript
复制
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出乎意料地为空的屏幕快照:

补充说明:

我已经尝试在1.5.20.

  • Android中更改其他值,并且它们都会更新,因此所包含的定义肯定是使用的。在试图以代码访问字段时,

  • 字段也是空的。

  • Kotlin版本的

Studio 2020.3.1修补程序1.

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-08-20 19:32:56

我很确定这是因为你们有相互参照。构造函数中的板引用项,反之亦然。两个枚举类的成员之一在另一个类之前实例化,因此在引用其他值时,对其他值的引用仍然是空的。这是在Kotlin中获得对null的非空引用(如果您的Board参数是非空的话),您可以做一些不应该做的事情,比如从构造函数中调用open函数,这是一种卑鄙的方法。

基本上,枚举不能安全地相互引用,因为它们是如何编译并在实例化时表现的。编译器是否应该显示针对此条件的警告或错误?可能吧,但显然不是。

下面是这个问题的一个最小可复制示例:

代码语言:javascript
复制
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.X引用。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/68866453

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档