Initialize enum from associated value

Viewed 3646

I would like to initialize enum by its associated value.

My enum:

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

I would like to initialize it as such:

val direction = DirectionSwiped(raw: 4)

But I get this error:

Enum type cannot be instantiated

Why is this happening? In Swift, this functionality works like this:

enum Direction: Int {
    case right = 2
}

let direction = Direction(rawValue: 2)

How can I make it work in Kotlin?

2 Answers

Yes you can

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 }

This would be the correct way to access the instances of the enum class

What you are trying to do is create a new instance outside the definition site, which is not possible for enum or sealed classes, that's why the error says the constructor is private

As the error says, you cannot instantiate enums in Kotlin. A possible workaround would be to use a map and 2 helper methods to get enum values from raw values and vice versa:

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]
    }
}

Usage:

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