Kotlin 枚举中的循环引用
Circular reference in Kotlin Enum
如何创建带有循环引用的枚举 class?
简单示例(取自):
enum class Hand(val beats: Hand) {
ROCK(SCISSORS), // Enum entry 'SCISSORS' is uninitialized here
PAPER(ROCK),
SCISSORS(PAPER);
}
由于 val
属性禁止重新分配,所以这个问题通常很难解决,通常表明您的数据模型存在问题。有关更广泛背景下的讨论,请参阅 .
然而,这个简单的例子可以使用 val
property with custom getter (thus without a backing field). Using when
来解决,getter 可以用一种非常可读的方式定义:
enum class Hand {
ROCK,
PAPER,
SCISSORS;
val beats: Hand
get() = when (this) {
ROCK -> SCISSORS
PAPER -> ROCK
SCISSORS -> PAPER
}
}
另一种解决方案(类似于 ) is to use sealed classes。由于概念约束较少,与 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
}
}
1个人意见
免责声明:我没有关于这些解决方案如何与经典 Java 结合使用的信息。
没有流控制语句的 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
}
在当前的 Kotlin 中,您可以将 val
s 与密封的 class 一起使用,就像 enum
:
一样
sealed class Hand(val beats: Hand) {
object ROCK : Hand(SCISSORS)
object PAPER : Hand(ROCK)
object SCISSORS : Hand(PAPER)
}
循环引用仍然存在,但不会造成任何问题。
这很奇怪,因为它与 enum
几乎相同,但没有自动序列化。
如何创建带有循环引用的枚举 class?
简单示例(取自
enum class Hand(val beats: Hand) {
ROCK(SCISSORS), // Enum entry 'SCISSORS' is uninitialized here
PAPER(ROCK),
SCISSORS(PAPER);
}
由于 val
属性禁止重新分配,所以这个问题通常很难解决,通常表明您的数据模型存在问题。有关更广泛背景下的讨论,请参阅
然而,这个简单的例子可以使用 val
property with custom getter (thus without a backing field). Using when
来解决,getter 可以用一种非常可读的方式定义:
enum class Hand {
ROCK,
PAPER,
SCISSORS;
val beats: Hand
get() = when (this) {
ROCK -> SCISSORS
PAPER -> ROCK
SCISSORS -> PAPER
}
}
另一种解决方案(类似于 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
}
}
1个人意见
免责声明:我没有关于这些解决方案如何与经典 Java 结合使用的信息。
没有流控制语句的 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
}
在当前的 Kotlin 中,您可以将 val
s 与密封的 class 一起使用,就像 enum
:
sealed class Hand(val beats: Hand) {
object ROCK : Hand(SCISSORS)
object PAPER : Hand(ROCK)
object SCISSORS : Hand(PAPER)
}
循环引用仍然存在,但不会造成任何问题。
这很奇怪,因为它与 enum
几乎相同,但没有自动序列化。