Kotlin:如何在Lambda中保留多返回逻辑
解决Kotlin Lambda中
return不允许的问题 你遇到的这个报错核心原因是非内联lambda不支持非局部return——你的safely函数不是inline的,所以lambda里的return会试图直接返回外层的doSomething函数,这在Kotlin里是不被允许的。下面给你三个可行的解决方案,根据你的需求选择就行:
方案1:把safely改成内联函数(最简洁)
如果可以修改safely函数的定义,直接给它加上inline关键字就行。内联函数会把lambda的代码直接嵌入到调用处,这样lambda里的return就相当于直接返回外层的doSomething,完全符合你的预期:
private inline fun <T> safely(block: () -> T, fallback: T): T { return try { block() } catch(exc: SomeException) { // 记录异常/执行一些逻辑 fallback } }
修改后你原来的doSomething代码完全不用改,就能正常运行了。
方案2:使用带标签的局部return(不改动safely)
如果不想修改safely函数,你可以给lambda加上标签,用return@标签来指定返回这个lambda的结果,而不是外层函数:
fun doSomething(): List<String> = safely( block = result@{ // 给lambda加个自定义标签 val list = mutableListOf<String>("Hello") fun someCheck1() = false fun someCheck2() = true do { if(someCheck2()) { return@result arrayListOf<String>("Hello", "World") // 用标签指定返回当前lambda } } while (someCheck1()) list // 最后直接返回列表,无需return }, fallback = arrayListOf<String>() )
这种方式完全不需要改动safely的实现,只是调整lambda里的return写法。
方案3:用变量存储结果,避免使用return
如果觉得带标签的return不够直观,也可以用一个变量来保存最终要返回的结果,通过break跳出循环,最后返回变量:
fun doSomething(): List<String> = safely({ val list = mutableListOf<String>("Hello") fun someCheck1() = false fun someCheck2() = true var finalResult: List<String>? = null do { if(someCheck2()) { finalResult = arrayListOf<String>("Hello", "World") break // 找到目标结果后直接跳出循环 } } while (someCheck1()) finalResult ?: list // 如果循环没找到结果,就返回初始的list }, arrayListOf<String>())
这种写法更偏向传统的命令式风格,适合不习惯Kotlin标签return的场景。
内容的提问来源于stack exchange,提问作者Eduardo
相关产品推荐
相关产品推荐

