Kotlin Enum的循环参考

Mic*_*off 5 enums circular-reference kotlin

如何创建带循环引用的枚举类?

简单的例子(取自这个Java问题):

enum class Hand(val beats: Hand) {
    ROCK(SCISSORS), // Enum entry 'SCISSORS' is uninitialized here
    PAPER(ROCK),
    SCISSORS(PAPER);
}
Run Code Online (Sandbox Code Playgroud)

Mic*_*off 7

由于禁止对val属性进行重新分配,因此通常很难解决此问题,并且通常表明数据模型存在问题.有关更广泛背景下的讨论,请参阅此问题/答案.

但是,可以使用具有自定义getter 的val 属性来解决此简单示例(因此没有支持字段).使用时when,可以用非常易读的方式定义getter:

enum class Hand {
    ROCK,
    PAPER,
    SCISSORS;

    val beats: Hand
        get() = when (this) {
            ROCK -> SCISSORS
            PAPER -> ROCK
            SCISSORS -> PAPER
        }
}
Run Code Online (Sandbox Code Playgroud)

另一种解决方案(类似于Eugen Pechanec答案)是使用密封类.由于它们的较少约束的概念,实现是1相比,稍微简单和更具有可读性enum与重写特性.

sealed class Hand {
    abstract val beats: Hand

    object ROCK: Hand() {
        override val beats = SCISSORS
    }

    object PAPER: Hand() {
        override val beats = ROCK
    }

    object SCISSORS: Hand() {
        override val beats = PAPER
    }
}
Run Code Online (Sandbox Code Playgroud)

1个人意见

免责声明:我没有关于这些解决方案如何与经典Java结合使用的信息.


Eug*_*nec 6

没有流量控制语句的 mhoff 答案的替代方法:

enum class Hand {
    ROCK {
        override val beats: Hand
            get() = SCISSORS
    },
    PAPER {
        override val beats: Hand
            get() = ROCK
    },
    SCISSORS {
        override val beats: Hand
            get() = PAPER
    };

    abstract val beats: Hand
}
Run Code Online (Sandbox Code Playgroud)