Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Scope of variable defined in for loop header

Tags:

kotlin

I noticed that the following Kotlin code compiles and executes successfully:

for (i in 1..2) {
    val i = "a"
    print(i)
}

This prints aa. However, I failed to find rationale behind the decision to allow this kind of variable shadowing. I would say that this is not a good practice, and is prohibited even in Java.

I think that Kotlin designers did a great work of improving Java syntax and accommodating it to the everyday practical use, so I must be missing something here?

like image 271
Dragan Bozanovic Avatar asked Jul 16 '16 22:07

Dragan Bozanovic


1 Answers

Kotlin does not restrict variable shadowing in any way. The rationale is simple: "consistency."

Since you could shadow variables in most other places why would you exclude only some loop variables from the allowed options? Why would they be so special? It is an arbitrary difference.

Any scope can shadow a variable used in another scope. It is NOT good practice and does produce a compiler warning -- but it is allowed.

If you want to engage in a dialog with the contributors of the project, try the discussion forum or slack channel, both are linked from the Kotlin Community page. Otherwise if you feel it is a bug please add an Issue report to Kotlin YouTrack and the answer you receive there will be definitive as well.

In the meantime, you are free to write nonsensical code such as:

val i = 1
class Foo() {
    val i = "monkey"
    init { println(i) }
    @Test fun boo() {
        println(i)
        val i = i.length
        println(i)
        if (i == 6) {
            val i = Date(System.currentTimeMillis() + i) // Shadow warning
            println(i)
        }
        for (i in 0..i) {                                // Shadow warning
            val i = "chimp $i"                           // Shadow warning
            println(i)
        }
        InnerFoo()
    }
    class InnerFoo() {
        val i: Long = 100L
        init { println(i) }
    }
}

Which in Kotlin 1.0.3 produces 3 warnings.

Warning:(15, 21) Kotlin: Name shadowed: i
Warning:(18, 18) Kotlin: Name shadowed: i
Warning:(19, 21) Kotlin: Name shadowed: i

And outputs:

monkey
monkey
6
Sun Jul 17 11:31:23 UYT 2016
chimp 0
chimp 1
chimp 2
chimp 3
chimp 4
chimp 5
chimp 6
100

like image 179
4 revs Avatar answered Oct 08 '22 15:10

4 revs