I have seen many interesting topics about Kotlin on portal.kotlin-academy.com/#/ recently. Personally, I think it is very suitable for Kotlin lovers, interested partners can consult by themselves.
The interesting Kotlin series records their understanding of each question.
0 x04: Lambda runnables
fun run(a) {
val run: () -> Unit = {
println("Run run run!")}object : Runnable {
override fun run(a) = run()
}.run()
}
fun main(args: Array<String>) {
run()
}
Copy the code
What is the result of the above code? Optional:
- “Run run run!”
- Doesn’t compile
- StackOverflowError
- None of the above
Think about it and write down the answer in your mind.
Analysis of the
Focus on the
fun run(a) {
val run: () -> Unit = {
println("Run run run!")}object : Runnable {
override fun run(a) = run()
}.run()
}
Copy the code
The outermost layers, run() and main(), are one hierarchy and are both in-file functions, which are static functions. A variable is defined in run()
val run: () -> Unit = {
println("Run run run!")}Copy the code
The run variable is a function type variable of type () -> Unit. An anonymous object is also defined
object : Runnable {
override fun run(a) = run()
}.run()
Copy the code
Define an anonymous object that implements the Runnable interface and call its run() method. The implementation of the run() method in the Runnable interface is the run function type variable that precedes the call.
Comb through each part of the topicrun
The problem will be solved.
So, starting with main, the entry to function execution, the order of execution is as follows:
Graph LR main function --> static function run --> anonymous object run --> function type run
So eventually the function type variable run will be called and executed
println("Run run run!")
Copy the code
Therefore, the correct answer is:
Option 1. Run Run Run!
The anonymous object in the problem could be Lambda shorthand, which would make it even more confusing to see run all over the screen.
fun run(a) {
val run: () -> Unit = {
println("Run run run!")
}
Runnable { run() }.run()
}
fun main(args: Array<String>) {
run()
}
Copy the code
extension
Adjust the code in the problem
fun run(a) {
val run: () -> Unit = {
println("Run run run!")}// Add a new run function
fun run(a) = println("Hello World")
object : Runnable {
override fun run(a) = run()
}.run()
}
fun main(args: Array<String>) {
run()
}
Copy the code
What does the program run console output at this point?
Answer: Hello World.
There is a call priority issue involved.
Here’s a question on StackOverflow about this:
Stackoverflow.com/questions/5…
There’s also a Github post that goes into detail:
Github.com/JetBrains/k…
Interested friends can consult by themselves.
If you want the program to say Run Run Run! , some adjustments are needed:
fun run(a) {
val run: () -> Unit = {
println("Run run run!")}fun run(a) = println("Hello World")
object : Runnable {
override fun run(a) = (run)()
}.run()
}
fun main(args: Array<String>) {
run()
}
Copy the code
or
fun run(a) {
val run: () -> Unit = {
println("Run run run!")}fun run(a) = println("Hello World")
object : Runnable {
override fun run(a) = run.invoke()
}.run()
}
fun main(args: Array<String>) {
run()
}
Copy the code
conclusion
- Anonymous objects can call functions and variables in their scope.
- There are two ways to call a function type variable:
(a)
和invoke()
. - SAM conversion Lambda