枚举类的子集

问题描述 投票:0回答:1

在 Kotlin 中,是否可以定义枚举的子集?

enum class Shape {
    FULL_HEIGHT_WALL, HALF_HEIGHT_WALL, FULL_HEIGHT_CORNER, HALF_HEIGHT_CORNER, SOMETHING_ELSE
}

fun Shape.isFullHeight() = when (this) {
    Shape.FULL_HEIGHT_WALL -> true
    Shape.FULL_HEIGHT_CORNER -> true
    else -> false
}

fun Shape.isHalfHeight() = when (this) {
    Shape.HALF_HEIGHT_WALL -> true
    Shape.HALF_HEIGHT_CORNER -> true
    else -> false
}

fun test(s: Shape) = when {
    s.isFullHeight() -> 1.0f
    s.isHalfHeight() -> 0.5f
    s == Shape.SOMETHING_ELSE -> 0.42f
    // else?!
}

函数

isFullHeight
对于
Shape
的一个子集成立,函数
isHalfHeight
对于另一个子集成立。 test函数的
when
语句应该是详尽的;但由于 Kotlin 不明白检查后不会保留任何枚举项,因此它需要一个 else 情况。这有点不幸,因为如果我添加一个 else 情况,如果我添加另一个形状并忘记更新
test
函数,编译器不会抱怨。

那么,是否可以重写此代码,以便 Kotlin 理解我正在检查子集?如果没有,这是否在路线图上? (我认为 TypeScript 能够做到这一点。)

kotlin enums subset
1个回答
0
投票

您可以创建一个额外的

Height
枚举。然后您可以使用
Height?
来表示全部、一半或“其他”(
null
)。

enum class Height {
    FULL, HALF
}

enum class Shape {
    FULL_HEIGHT_WALL, HALF_HEIGHT_WALL, FULL_HEIGHT_CORNER, HALF_HEIGHT_CORNER, SOMETHING_ELSE   
}

val Shape.height get() = when (this) {
    Shape.FULL_HEIGHT_WALL -> Height.FULL
    Shape.FULL_HEIGHT_CORNER -> Height.FULL
    Shape.HALF_HEIGHT_WALL -> Height.HALF
    Shape.HALF_HEIGHT_CORNER -> Height.HALF
    else -> null
}

fun test(s: Shape) = when(s.height) {
    Height.FULL -> 1.0f
    Height.HALF -> 0.5f
    null -> 0.42f
}

另一种方法是使用密封类型层次结构。通过实现接口来表示每个案例的高度,并使用

is
中的
when
来检查类型。

sealed interface Shape {
    object FullHeightWall: FullHeight
    object HalfHeightWall: HalfHeight
    object FullHeightCorner: FullHeight
    object HalfHeightCorner: HalfHeight
    object SomethingElse: Shape
}

sealed interface FullHeight: Shape
sealed interface HalfHeight: Shape

fun test(s: Shape) = when(s) {
    is FullHeight -> 1.0f
    is HalfHeight -> 0.5f
    Shape.SomethingElse -> 0.42f
}
© www.soinside.com 2019 - 2024. All rights reserved.