kotlinclosureselvis-operator

kotlin: can I use qualified return from a closure?


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?


Solution

  • 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.