The Programmers Guide To Kotlin - Anonymous and Lambda Functions |
Written by Mike James | ||||
Monday, 29 October 2018 | ||||
Page 3 of 3
ClosureClosure is one of the most mystifying aspects of lambdas. The Kotlin documentation makes a lot of the fact that a lambda has access to the local variables of any function that encloses it, but this is really just the way that local variable work rather than closure. Closure, in the way that most languages implement it, means having access to variables that were local but are no longer in scope. The simplest example of this is when a function returns a lambda. While the function is executing, the lambda has access to variables that are local to the function – but not only this, it has access to them when the function has completed and the local variables have been, in principle, destroyed. You can think of this as the lambda "capturing" the variables in a closure. Kotlin supports this sort of closure. For example, if we define a function that returns a simple lambda:
There are several interesting things about this function. The first is that its return type is ()->Unit, i.e. it returns a function that accepts no parameters and returns nothing, i.e. Unit. This is indeed the type of the lambda it returns. The lambda in question simply prints the value of a and adds one to it. Note that a is a local variable in myFunction and it is only accessible from within myFunction and it is destroyed when myFunction returns, i.e. it normally only exists while myFunction is active. If you now call myFunction to get an instance of the lambda:
and then call the lambda twice:
what do you think will happen? The answer is that it prints 1 followed by 2. The instance has access to the local variable that should have been destroyed when myFunction terminated, and it not only has access to its initial value but it can modify it. It is important to realize that each time you return a new instance of the lambda the local variable a is a new local variable. For example:
You will see 1,2 and then 1,2 printed because the variable a captured by mylambda1 is not the same as the a captured by mylambda2. Closure works with named and anonymous functions as well as pure lambda functions. In the case of named functions it has to be a local function and you have to use the :: operator. For example:
If you are unfamiliar with lambda functions or functions as first class objects you might be wondering what use closure is? There are a number of standard uses of closure, but perhaps the most useful is when you are defining an event handler of a callback function. Lambdas and anonymous functions make supplying a callback very easy. However, the callback is usually designed to process the end result of some long running task and this usually involves the function that created the callback. If the task wasn't long running you would have simply waited for it to complete and then processed its return value. The callback breaks up the original function into before the task and after the task. By allowing the callback access to the function’s local variables, closure allows a degree of communication between the original function and the callback. Inline Functionsfinal version in book Non-Local Returnsfinal version in book Reified Typefinal version in book Summary
This article is an extract from: Programmer's Guide To Kotlin Third Edition
You can buy it from: Amazon Contents
<ASIN:B0D8H4N8SK> To be informed about new articles on I Programmer, sign up for our weekly newsletter, subscribe to the RSS feed and follow us on Twitter, Facebook or Linkedin.
Comments
or email your comment to: comments@i-programmer.info <ASIN:1871962536>
|
||||
Last Updated ( Saturday, 03 November 2018 ) |