Initialization of val by destructuring in Kotlin

半城伤御伤魂 提交于 2020-01-21 19:01:44

问题


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?


回答1:


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:


15 Destructuring assignments

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.



来源:https://stackoverflow.com/questions/44515920/initialization-of-val-by-destructuring-in-kotlin

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!