crossinline: Allowing return

You might have funky code that tries doing a return from inside of a lambda expression:

fun beUseful(whenDone: () -> Unit) {
  // TODO something useful
  
  whenDone()
}

fun main() {
  beUseful {
    println("hello, world!")
    return
  }
  
  println("...and we're done!")
}

This fails to compile:

'return' is not allowed here

You cannot return from the middle of some lambda expression.

However, if you mark the function as inline:

inline fun beUseful(whenDone: () -> Unit) {
  // TODO something useful
  
  whenDone()
}

fun main() {
  beUseful {
    println("hello, world!")
    return
  }
  
  println("...and we're done!")
}

The code compiles… but ...and we're done! does not get printed. Effectively, what the inline keyword does is turn that code into:

fun main() {
  println("hello, world!")
  return
  
  println("...and we're done!")
}

As a result, we return from main() before we reach the second println() call.

If you want to block this sort of return from being used, add crossinline to the function type parameter declaration:

inline fun beUseful(crossinline whenDone: () -> Unit) {
  // TODO something useful
  
  whenDone()
}

fun main() {
  beUseful {
    println("hello, world!")
    return
  }
  
  println("...and we're done!")
}

Now, we are back to the original 'return' is not allowed here compiler error.


Prev Table of Contents Next

This book is licensed under the Creative Commons Attribution-ShareAlike 4.0 International license.