https://kotlinlang.org logo
#kotlin-native
Title
# kotlin-native
z

Zsolt Bencze

01/27/2023, 2:13 PM
👋 I wanted to see what the community thinks about enums in Kotlin. I had a discussion with a colleague and I learned that enums seem to be taking a back seat to sealed classes and interfaces. I was really surprised given that I come from a Swift background where enums are very important and widely used.
j

jw

01/27/2023, 2:15 PM
Swift enums and other language's enums (such as Rust) are far closer to sealed hierarchies than Kotlin's extremely basic, JVM-inspired(/limited) version of enums
e

ephemient

01/27/2023, 2:17 PM
since you're familiar with Swift: JVM enums cannot have associated values
so while Swift's
Copy code
enum Foo {
    case bar, baz
}
is mostly equivalent to
Copy code
enum class Foo {
    bar, baz
}
you can't translate
Copy code
enum Foo {
    case bar(Int)
    case baz
}
to a Kotlin
enum class
z

Zsolt Bencze

01/27/2023, 2:21 PM
I see.. I understand now. Enums in Kotlin are not equal to Swift in Kotlin.
e

ephemient

01/27/2023, 2:21 PM
that would be more closely represented by
Copy code
sealed class Foo {
    data class Bar(val value: Int) : Foo()
    object Baz : Foo()
}
instead. of course you could also translate an
enum
without associated values to `sealed class`+`object`, but while the usage is pretty similar in Kotlin, you lose some of the Java conveniences of
enum
that way
k

kevin.cianfarini

01/27/2023, 2:22 PM
Is there much difference on a machine code / bytecode level? I assume enums are better because it doesn’t require virtual dispatch whereas sealed hierarchies would. I don’t know if there’s other ancillary benefits too, though
e

ephemient

01/27/2023, 2:22 PM
there is a bit of a difference in bytecode, yes. virtual dispatch is… maybe confusing
j

jw

01/27/2023, 2:24 PM
enums are basically sealed value classes. so once we get those enums will mostly be obsolete aside from a syntactical terseness where they have an implicit backing integer and auto-assigned ordinals
k

kevin.cianfarini

01/27/2023, 2:25 PM
That’s a good point — referring to an instance of an enum by it’s ordinal is often a footgun. Especially for things like db persistence.
j

jw

01/27/2023, 2:25 PM
although sealed value classes can still box whereas enums are always boxed-by-default. you pass around the reference rather than the underlying ordinal. so still slightly different
e

ephemient

01/27/2023, 2:27 PM
Copy code
enum class Foo {
    Bar,
    Baz {
        override fun toString(): String = "baz"
    }
}
in bytecode this looks sorta like what
Copy code
class Foo private constructor(override val name: String) : Enum<Foo> {
    override fun toString(): String = name

    private class Baz(name: String) : Foo(name) {
        override fun toString(): String = "baz"
    }

    companion object {
        @JvmField
        val Bar = Foo("bar")
        @JvmField
        val Baz = Baz("baz")
        @JvmStatic
        fun values(): Array<Foo> = arrayOf(Bar, Baz)
    }
}
would compile to, except that you aren't allowed to subclass
Enum
yourself
(plus some other enum magic like ordinal and valueOf)
z

Zsolt Bencze

01/27/2023, 4:52 PM
This is really helpful, thanks!
6 Views