Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Kotlin enum constructor argument 'must be initialized' with companion object constant without qualifier name

Tags:

enums

kotlin

This code compiles successfully with the qualified name used to access the constants from the companion object:

enum class CampsiteCategoryCode(val code: String) {
  TENT(CampsiteCategoryCode.TENT_CODE), // intellij says 'Redundant qualifier name'
  OTHER(CampsiteCategoryCode.OTHER_CODE), // intellij says 'Redundant qualifier name'
  LODGING(CampsiteCategoryCode.LODGING_CODE), // intellij says 'Redundant qualifier name'
  RV(CampsiteCategoryCode.RV_CODE); // intellij says 'Redundant qualifier name'

  override fun toString() = code

  companion object {
    const val TENT_CODE = "tent"
    const val OTHER_CODE = "other"
    const val LODGING_CODE = "lodging"
    const val RV_CODE = "rv"
  }
}

However, the same code without the qualifier name fails compilation:

enum class CampsiteCategoryCode(val code: String) {
  TENT(TENT_CODE), // Variable 'TENT_CODE' must be initialized
  OTHER(OTHER_CODE), // Variable 'OTHER_CODE' must be initialized
  LODGING(LODGING_CODE), // Variable 'LODGING_CODE' must be initialized
  RV(RV_CODE); // Variable 'RV_CODE' must be initialized

  override fun toString() = code

  companion object {
    const val TENT_CODE = "tent"
    const val OTHER_CODE = "other"
    const val LODGING_CODE = "lodging"
    const val RV_CODE = "rv"
  }
}

Why does specifying the qualifier name allow this code to compile? Or put another way, why does not having the qualifier name make the code fail to compile?

like image 298
Braden Steffaniak Avatar asked Aug 19 '19 16:08

Braden Steffaniak


2 Answers

There are two solutions for that:

  1. make the variable a top-level declaration (as @baguIO mentioned)
  2. mention the scope explicitly (use CampsiteCategoryCode.TENT_CODE instead of just TENT_CODE)
like image 55
nepa Avatar answered Oct 13 '22 09:10

nepa


That companion object will be instantiated the moment your class becomes available (compile time). Then you are telling your class that, for it to become available, it needs a class that is not yet available (because you're compiling it at the moment and, apparently, Kotlin makes enum cases available before companion objects)

I can't tell for sure if this is intended from Kotlin, but to avoid this kind of cases, declare your constants outside this class

like image 28
baguIO Avatar answered Oct 13 '22 09:10

baguIO