Search code examples
while-loopkotlinvariable-initialization

Is it possible to init a variable in the while condition body for Kotlin?


In the code below:

    var verticesCount: Int // to read a vertices count for graph

    // Reading until we get a valid vertices count.
    while (!Assertions.checkEnoughVertices(
            verticesCount = consoleReader.readInt(null, Localization.getLocStr("type_int_vertices_count"))))
        // The case when we don't have enough vertices.
        println(String.format(Localization.getLocStr("no_enough_vertices_in_graph"),
                              Assertions.CONFIG_MIN_VERTICES_COUNT))

    val resultGraph = Graph(verticesCount)

we are getting next error on the last line:

Error:(31, 33) Kotlin: Variable 'verticesCount' must be initialized

Assertions.checkEnoughVertices accepts a safe type variable as an argument (verticesCount: Int), so it's impossible for verticesCount to be uninitialized or null here (and we're getting no corresponding errors on those lines).

What's going on on the last line when already initialized variable becomes uninitialized again?


Solution

  • The syntax you've used denotes a function call with named arguments, not the assignment of a local variable. So verticesCount = is just an explanation to the reader that the value which is being passed here to checkEnoughVertices corresponds to the parameter of that function named verticesCount. It has nothing to do with the local variable named verticesCount declared just above, so the compiler thinks you've still to initialize that variable.

    In Kotlin, the assignment to a variable (a = b) is not an expression, so it cannot be used as a value in other expressions. You have to split the assignment and the while-loop condition to achieve what you want. I'd do this with an infinite loop + a condition inside:

    var verticesCount: Int
    
    while (true) {
        verticesCount = consoleReader.readInt(...)
        if (Assertions.checkEnoughVertices(verticesCount)) break
    
        ...
    }
    
    val resultGraph = Graph(verticesCount)