Home > database >  How to auto-increment a list of const values in Kotlin?
How to auto-increment a list of const values in Kotlin?

Time:10-11

For example, how would I do something similar to the following, where all the values are unique:

private var id = 0
const val id0 = id   // Gives error: "Const 'val' initializer should be a constant value"
const val id1 = id  
const val idasdf = id  
const val idqwerty = id  
// Many more rows (sometimes 10s, potentially 1000s?), with random vals being added and removed occasionally

I would strongly prefer to use this way of setting many constants because it would look cleaner and when I add/remove random values, I don't have to worry about any uniqueness issues (it's okay for the values to change between builds, and the values don't need to be consecutive). (And, vals are added so that the list of them are in alphabetical order)

Workarounds that I'm not really interested in:

  • Using Java static final
  • Manually setting values
  • Using something like const val idasdf = "asdf".hashcode() also doesn't work for the same reason as using ... = i
  • Removing const, aka just using val id1 = i (because I want to learn more Kotlin or maybe another design pattern)

Sidenote: A long time ago floats and doubles couldn't be set as const in Kotlin, but they updated that. So, maybe (hopefully) this is in their backlog too? But, I haven't found it yet after a quick search.

ps: I'm working in Android. Maybe this note can expand the number of possible workarounds, like using IntDef

CodePudding user response:

Maybe I'm barking up the wrong tree here, but your requirements — a series of compile-time constants with consecutive integer values starting from 0 — look rather like an enum.

Would an enum class work in your case? The compiler assigns an integer value to each, which you can access with the ordinal field:

enum class Colour { RED, ORANGE, YELLOW, GREEN, BLUE }

fun main() {
    println(RED.ordinal)    // prints 0
    println(ORANGE.ordinal) // prints 1
}

CodePudding user response:

By definition a const is a value known at compile time. It is inlined as a hard-coded value at every usage site, so it cannot be initialized at runtime like this, and this pattern never will be possible unless they come up with some mechanism for incrementing a compile-time-only variable.

To get something that compiles like a Java static final field, use @JvmField.

private var id = 0
@JvmField val id0 = id  
@JvmField val id1 = id  
@JvmField val idasdf = id  
@JvmField val idqwerty = id  

There's not a lot of advantage here over simply using val though. I suppose it prevents a getter method from being generated. What are you hoping to gain by marking them const?

CodePudding user response:

const means "compile time constant". You cannot use the keyword const for a value that isn't known at compile time.

  • Related