Many libraries make extensive use of numeric enums.
Android programming has a special annotation @IntDef
to provide value checking.
However, defining numeric enums is cumberson:
// TODAY:
@NavigationMode var mode: Int = NAVIGATION_MODE_STANDARD
companion object {
@Retention(AnnotationRetention.SOURCE)
@IntDef(NAVIGATION_MODE_STANDARD.toLong(), NAVIGATION_MODE_LIST.toLong(), NAVIGATION_MODE_TABS.toLong())
annotation class NavigationMode
const val NAVIGATION_MODE_STANDARD = 0
const val NAVIGATION_MODE_LIST = 1
const val NAVIGATION_MODE_TABS = 2
}
It would by nice to be able to define numeric enums as easily as Java enums by declaring an integer numeric supertype.
// PROPOSAL:
var mode: NavigationMode = NAVIGATION_MODE_STANDARD
enum class NavigationMode: Int { // Int as superclass
NAVIGATION_MODE_STANDARD,
NAVIGATION_MODE_LIST,
NAVIGATION_MODE_TABS
}
At bytecode level, this should produce the same code as @IntDef
above. In this case, field mode
is of type Int
. All enum elements are inlined numeric constants. Assignment of numeric values should be possible, creating warnings if the value cannot be guaranteed to match an enum value. Exhaustive when
statements can be supported.
Explicit values can be supplied with constructor parameters:
enum class NavigationMode: Int {
NAVIGATION_MODE_STANDARD(-1),
NAVIGATION_MODE_LIST(1),
NAVIGATION_MODE_TABS(4)
}
As an optional feature, the compiler could create a StringArray
or Map
with the names of the elements (for logging), such that NavigationMode.names[1]
returns "NAVIGATION_MODE_LIST"
.
At least Int
and Long
should by available as numeric supertypes. Short
and Byte
would also be useful, but may be harder since they lack respective literals in the JVM.