Why can't a variable be correctly initialized in an inline function, like in java?

We know that the body of a lambda is lazily good, because if we don't call lambda, the code in the lambda body will never be called.

We also know in any function language that a variable can be used in the / lambda function, even if it is not initialized, for example, javascript, ruby, groovy and .etc, for example, the groovy code below can work fine:

def foo

def lambda = { foo }

foo = "bar"

println(lambda())
//      ^--- return "bar"

We also know that we can access an uninitialized variable if the catch block initialized the variable when an exception occurs in a try block in Java, for example:

//  v--- m is not initialized yet
int m;

try{ throw new RuntimeException(); } catch(Exception ex){ m = 2;}

System.out.println(m);// println 2

, ? , Kotlin - , , , , . - "" . :

var a:Int
val lambda = { a }// lambda is never be invoked
//             ^--- a compile error thrown: variable is not initialized yet
a = 2

Q: ? , - Java, , ObjectRef , : - ". :

var a:Int
run{ a = 2 }// a is initialized & inlined to callsite function

//      v--- a compile error thrown: variable is not initialized yet
println(a)

, , element ObjectRef , @hotkey .

Q: Kotlin , catch-, , java? :

var a: Int

try {
    run { a = 2 }
} catch(ex: Throwable) {
    a = 3
}

//      v--- Error: `a` is not initialized
println(a)

, @hotkey , try-catch Kotlin , :

var a: Int = try {
    run { 2 }
} catch(ex: Throwable) {
    3
}

//      v--- println 2
println(a);

Q: , run ? :

val a = run{2};

println(a);//println 2

java, :

int a;
try {
    a = 2;
} catch (Throwable ex) {
    a = 3;
}

System.out.println(a); // println 2
0
2

Q: ?

. , , , , , , . kotlin , .

: Kotlin , catch-, , java?

run , , . run, , .

try-catch a = run { 2 }, run { a = 2 }, .

Q: , ?

, . Java, , Java Kotlin, . , - Java, , Kotlin.

+2

...

val a: Int by lazy { 3 }

, 3. , a .

Edit

, , " ". , , ( ). , , , . , , , , , , .

, , ( , ).

( 1.1 )

import kotlin.reflect.*

//...
var a:Int by object {
    private var backing : Int? = null
    operator fun getValue(thisRef: Any?, property: KProperty<*>): Int =
        backing ?: throw Exception("variable has not been initialized") 
    operator fun setValue(thisRef: Any?, property: KProperty<*>, value: Int) {
        backing = value
    }
}
var lambda = { a }

// ...
a = 3
println("a = ${lambda()}")

, , ( , lazy ). lazy.

, . .

+1

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


All Articles