kotlin 从关联值初始化枚举

hsvhsicv  于 2023-05-07  发布在  Kotlin
关注(0)|答案(4)|浏览(145)

我想用枚举的相关值初始化枚举。
我的枚举:

enum class DirectionSwiped(raw: Int){
    LEFT(4),
    RIGHT(8);
}

我想把它初始化为:

val direction = DirectionSwiped(raw: 4)

但我得到了这个错误:
无法示例化枚举类型
为什么会这样?在Swift中,这个功能是这样工作的:

enum Direction: Int {
    case right = 2
}

let direction = Direction(rawValue: 2)

如何在Kotlin中使用它?

nbysray5

nbysray51#

你可以的

enum class DirectionSwiped(val raw: Int){
    LEFT(4),
    RIGHT(8);
}

val left = DirectionSwiped.LEFT
val right = DirectionSwiped.RIGHT

val leftRaw = DirectionSwiped.LEFT.raw
val rightRaw = DirectionSwiped.LEFT.raw

val fromRaw = DirectionSwiped.values().firstOrNull { it.raw == 5 }

这是访问enum class示例的正确方法
你试图做的是在定义站点之外创建一个新示例,这对于enumsealed类是不可能的,这就是为什么错误说构造函数是private的原因。

bakd9h0s

bakd9h0s2#

正如错误所说,你不能在Kotlin中示例化枚举。一个可能的解决方法是使用一个map和2个helper方法从原始值中获取枚举值,反之亦然:

enum class DirectionSwiped {
    LEFT,
    RIGHT;

    fun toRaw() = enumToRaw[this]
    companion object {
        val rawToEnum = mapOf(
                4 to LEFT,
                8 to RIGHT
        )
        val enumToRaw = rawToEnum.entries.associate{(k,v)-> v to k}
        fun ofRaw(raw: Int): DirectionSwiped? = rawToEnum[raw]
    }
}

使用方法:

val direction = DirectionSwiped.ofRaw(4) // LEFT
val raw = DirectionSwiped.LEFT.toRaw() // 4
mctunoxg

mctunoxg3#

这里有一个更通用的解决方案。您可以添加您希望fun instance(raw:)保持可用的情况,而无需更多的编写添加情况。

enum class DirectionSwiped(val raw: Int){
    LEFT(4),
    RIGHT(8);
    companion object {
        fun instance(raw: Int): DirectionSwiped? {
            return values().firstOrNull { it.raw == raw }
        }
    }
}

val direction = DirectionSwiped.instance(4)
println(direction?.raw ?: "null")
p8ekf7hl

p8ekf7hl4#

你可以通过重载DirectionSwiped()来模拟Swift的语法:

enum class DirectionSwiped(private val raw: Int) {
    LEFT(4),
    RIGHT(8);
    
    companion object {
        operator fun invoke(raw: Int): DirectionSwiped? = 
            DirectionSwiped.values().firstOrNull { it.raw == raw }
    }
}

使用方法:

val direction = DirectionSwiped(raw = 4)

你可以在这个Kotlinplayground脚本中尝试上面的内容。
然而,我建议不要使用这种解决方案,因为它可能会让读者感到惊讶。
一个不那么令人惊讶,因此更好的变体是:

enum class DirectionSwiped(private val raw: Int) {
    LEFT(4),
    RIGHT(8);
    
    
    companion object {
        fun byRaw(raw: Int): DirectionSwiped? = 
            DirectionSwiped.values().firstOrNull { it.raw == raw }
    }
}

val direction = DirectionSwiped.byRaw(4)

相关问题