Why the code in an object expression can access variables from the scope that contains it in kotlin?

后端 未结 5 1183
醉梦人生
醉梦人生 2021-01-01 10:49

In Kotlin,the code in an object expression can access variables from the scope that contains it, just like the following code:

fun countClicks(window: JCompo         


        
5条回答
  •  既然无缘
    2021-01-01 11:42

    In Java, you can only capture (effectively) final variables in anonymous classes and lambdas. In Kotlin, you can capture any variable, even if they are mutable.

    This is done by wrapping any captured variables in instances of simple wrapper classes. These wrappers just have a single field that contains the captured variables. Since the instances of the wrappers can be final, they can be captured as usual.

    So when you do this:

    var counter = 0
    { counter++ }()   // definition and immediate invocation, very JavaScript
    

    Something like this happens under the hood:

    class Ref(var value: T) // generic wrapper class somewhere in the runtime
    
    val counter = Ref(0);      // wraps an Int of value 0
    { counter.value++ }()      // captures counter and increments its stored value
    

    The actual implementation of the wrapper class is written in Java, and looks like this:

    public static final class ObjectRef implements Serializable {
        public T element;
    
        @Override
        public String toString() {
            return String.valueOf(element);
        }
    }
    

    There are also additional wrappers called ByteRef, ShortRef, etc. that wrap the various primitives so that they don't have to be boxed in order to be captured. You can find all the wrapper classes in this file.

    Credits go to the Kotlin in Action book which contains the basics of this information, and the example used here.

提交回复
热议问题