Is there a way to nest an enum within a data class in Kotlin?

10,548

Solution 1

There is no kotlin specification for the syntax at present. if you want to find the specification you can see JLS, because Kotlin is based on Java, so some specifications also appropriate in Kotlin.

A nested enum type is implicitly static. It is permitted for the declaration of a nested enum type to redundantly specify the static modifier.

This implies that it is impossible to declare an enum type in the body of an inner class (§8.1.3), because an inner class cannot have static members except for constant variables.

and, all local classes are inner classes.

So the enum class can be declared anywhere except the local function scope and inner classes.

If you don't sure where can define a type you can try to prompt the scope in turn: local > class > top, then the kotlin compiler will give you the correct compiler error message to you. for example:

IF you define a const val in the local function, the compiler report the error as below:

fun local() {
    const val foo="bar"
    // ^--- the modifier `const` is not applicable to `local variable`  
}

IF you define a const val in the common class/interface, the compiler will report the error as below:

interface Foo {
  const val foo = "bar"
  //^--- `const val` only allowed on top-level or objects.
}

Solution 2

Yes, you can nest the enum in a data class, but not in a function:

data class Outer(val a: InnerEnum) {
    enum class InnerEnum { A, B }
}

fun foo() {
    val o = Outer(Outer.InnerEnum.A)
    println(o) // --> Outer(a=A)
}
Share:
10,548
Julian A.
Author by

Julian A.

Updated on June 17, 2022

Comments

  • Julian A.
    Julian A. almost 2 years

    Is there a way to nest an enum within a data class in Kotlin?

    data class D(val a:Any) {
        enum class E {F,G}
        ...
    }
    

    Or to declare it inline within a function?

    fun foo() {
        enum class E {F,G}
        doSomething()
    }
    

    I can't find documentation on the rules for where enums are allowed to be declared.

  • Julian A.
    Julian A. almost 7 years
    Thanks for your answer. What do you mean by "prompt the scope in turn"? Is that a feature of IntelliJ?
  • holi-java
    holi-java almost 7 years
    @Julian just as put your code in each scope in turn. and I have gave an example of const val.
  • glee8e
    glee8e almost 7 years
    Actually there is a syntax spec on the official site: kotlinlang.org/docs/reference/grammar.html It's rather incomplete though. There are edge cases that the grammar shown on that page allows but is rejected by compiler. I can't remember a concret case ATM, though. Feel free to add this info to your anwser.
  • holi-java
    holi-java almost 7 years
    @glee8e No. the gammar is broad and it is not precised. just like as java gammer.