kotlin: can I use qualified return from a closure?

438 Views Asked by At

I want to log&return on null values from a supplier.

Without logging this works fine:

    fun check_plain(supplier: Supplier<String?>) {
        val arg: String = supplier.get() ?: return
        // do checking
    }

However if I also log behind elvis, I get an error:

    fun check_log(supplier: Supplier<String?>) {
        val arg: String = supplier.get() ?: {
            logger.info { "Nothing interesting here" }
            return@check_log // 'return' is not allowed here
        }
        // do checking
    }

I work around it, but it's not equivalent, I loose the formal non-nullability:

    fun check_if(supplier: Supplier<String?>) {
        val arg: String? = supplier.get().also {
            if (it == null) {
                logger.info { "Nothing interesting here" }
                return@check_if
            }
        }
        // do checking
    }

Can I keep the Elvis somehow?

1

There are 1 best solutions below

0
Sweeper On BEST ANSWER

return is not allowed there because the lambda is not inlined. For more info, see the language spec.

For this simple case, you can just do:

val arg: String = supplier.get() ?: return logger.info { "Nothing interesting here" }

If you have more statements you want to run, use run:

val arg: String = supplier.get() ?: return run {
    logger.info { ... }
    logger.info { ... }
    logger.info { ... }
}

or:

val arg: String = supplier.get() ?: run {
    logger.info { ... }
    logger.info { ... }
    logger.info { ... }
    return
}

Note that return is allowed inside run because run is inlined.