Why can't use continue in let or run

Viewed 680

Why it is not allowed to continue from let function?

This code:

fun foo(elements: List<String?>) {
    for (element in elements) {
        element?.let {
            continue  // error: 'break' or 'continue' jumps across a function or a class boundary
        }
    }
}

And even this code:

fun foo(elements: List<String?>) {
    loop@ for (element in elements) {
        element?.let {
            continue@loop  // error: 'break' or 'continue' jumps across a function or a class boundary
        }
    }
}

Does not compile with error:

'break' or 'continue' jumps across a function or a class boundary


I know that in this particular case I can use filterNotNull or manual check with smart cast, but my question is why it is not allowed to use continue here?


Please vote for this feature here: https://youtrack.jetbrains.com/issue/KT-1436

1 Answers

These would be called "non-local" breaks and continues. According to the documentation:

break and continue are not yet available in inlined lambdas, but we are planning to support them too.

Using a bare (e.g. non-local) return inside a lambda is only supported if it is an inlined lambda (because otherwise it doesn't have awareness of the context it is called from). So break and continue should be able to be supported. I don't know the reason for the functionality to be delayed.

Note, there are work-arounds for both of them by run either inside or outside the loop, and taking advantage of the fact that at least non-local returns are supported for inline functions.

fun foo(elements: List<String?>) {
    run {
        for (element in elements) {
            element?.let {
                println("Non-null value found in list.")
                return@run // breaks the loop
            }
        }
    }
    println("Finished checking list")
}

fun bar(elements: List<String?>) {
    for (element in elements) {
        run {
            element?.let {
                return@run // continues the loop
            }
            println("Element is a null value.")
        }
    }
}
Related