Initially I wanted to achieve
class NotationDiceRoll(notation: String) {
val rolls: Int
val sides: Int
init {
parseNotation(notation)
}
private fun parseNotation(notation: String) {
rolls = 1
sides = 4
}
}
But Kotlin complains that "Val cannot be reassigned".
It seems that the only place where the vals can be assigned is the init block. Alright then, it is more obvious after all. So I changed it to
class NotationDiceRoll(notation: String) {
val rolls: Int
val sides: Int
init {
(rolls, sides) = parseNotation(notation)
}
private fun parseNotation(notation: String): Pair<Int, Int> {
return Pair(1, 4)
}
}
Now Kotlin complains that "Variable 'rolls' must be initialized".
It can be solved by
init {
val(rolls, sides) = parseNotation(notation)
this.rolls = rolls
this.sides = sides
}
but it is less elegant.
So my question is: is the destructuring really possible only with the vals being declared on the same line?
This feature is called a destructuring declaration, and that's what it is, a declaration of new variables with immediate assignment to them. It's not just that variables declared with val
can't be used in later destructuring, no variables declared earlier can. For example, the following doesn't work either:
var x = 0
var y = 0
(x, y) = Pair(1, 2)
It's worth noting though that the feature you're looking for (destructuring assignments) was one of the possible future features for Kotlin out of the 20 cards that were available to be voted on at the Kotlin 1.1 event. While the online survey is no longer up, you can see the description of the feature on this image, it's card number 15. It's a bit hard to make out, so here's what's on it:
Kotlin already has destructuring declarations:
val (name, address) = findPerson(...)
Some users request destructuring assignments,
ie. assign to multiple previously declared var
's:
var name = ...
...
var address = ...
...
(name, address) = findPerson(...)
Do you need this feature?
Update: here's an official doc with the proposed features, and here's the survey results.