Why can't using block safely initialize var?

Why does this give a compilation error?

val autoClosable = MyAutoClosable()
var myVar: MyType
autoClosable.use {
    myVar= it.foo()
}
println(myVar) // Error: Variable 'myVar' must be initialized

Maybe the compiler just sees it { myVar= it.foo() }as a function that is passed to another function and does not know when or even if it will be executed?

But since it useis not just a function, but a Kotlin replacement for Java try-with-resource, some special knowledge about this would be appropriate, would it not? Right now I am forced to initialize myVarwith the help of some fictitious meaning, which is not at all in the spirit of Kotlin.

+4
source share
3 answers

use { ... } , , (, , ), - . , , .

, . :

inline fun ignoreBlock(block: () -> Unit) = Unit

var myVar: MyType
ignoreBlock { myVar = it.foo() }
println(myVar) // Expectedly, `myVar` stays uninitialized, and the compiler prohibits it

, , use ( , ) :

val myVar = autoClosable.use {
    it.foo()
}

, , try :

val myVar = try {
    autoClosable.use {
        it.foo()
    }
} catch (e: SomeException) {
    otherValue   
}

, , lambda , Kotlin , . .

+6

it.foo() use , autoClosable, . myVar .

, .

-1

, use , , call-site, myVar .

IF myVar , MyType . :

//      v--- the actual type here is MyType
var myVar: MyType = TODO()

autoClosable.use {
    myVar.todo()
}

IF myVar lambda , - ObjectRef. ? , Java . myVar -. :

//  v--- the actual type here is an ObjectRef type.
var myVar: MyType

autoClosable.use {
    myVar = autoClosable.foo()
}

, println(myVar), , ObjectRef . .

IF - , , :

//  v--- the actual type here is an ObjectRef type.
var myVar: MyType
try {
    autoClosable.use {
        myVar = it.foo()
    }
} catch(e: Throwable) {
    myVar = MyType()
}

//       v--- Error: Variable 'myVar' must be initialized
println(myVar) 

, myVar MyType, . :

var myVar: MyType
try {
    TODO()
} catch(e: Throwable) {
    myVar = MyType()
}

println(myVar) // works fine

Why didn't kotlin optimize its built-in functions for direct use MyTypefor recording?

The only thing I think the compiler does not know myVaris whether it will be used in the lambda body of another uninline function in the future. or kotlin want to maintain a semantic sequence for all functions.

-1
source

Source: https://habr.com/ru/post/1681963/


All Articles