【问题标题】:A 'return' expression required in a function with a block body despite inlined lambda which has the return尽管内联 lambda 具有返回值,但在具有块体的函数中需要一个“返回”表达式
【发布时间】:2020-11-02 20:23:04
【问题描述】:

我正在尝试创建内联的 try-catch 辅助函数,但由于内联 lambda 中出现 return 语句而遇到编译错误。下面是一些演示相同问题的代码

fun isStringEmpty(myString: String): Boolean {
    stringOpHelper { 
        return myString.length == 0
    }
}
inline fun <T> stringOpHelper(fn: () -> T) {
    println("performing string operation")
    fn()
}

如果在内联函数调用之后添加返回值或抛出异常,这将编译为所需的效果,但该代码应该无法访问。例如:

fun isStringEmpty(myString: String): Boolean {
    stringOpHelper { 
        return myString.length == 0
    }
    TODO("this is actually unreachable")
}
inline fun <T> stringOpHelper(fn: () -> T) {
    println("performing string operation")
    fn()
}

我的期望是编译器会看到stringOpHelper 总是调用fn() 并且isStringEmpty 中的fn 总是返回,所以内联的stringOpHelper 调用总是返回。

是否可以以一种避免调用函数中无法访问的异​​常/返回的方式定义内联辅助函数?否则,这是不可能的原因是什么?

【问题讨论】:

    标签: kotlin lambda inline


    【解决方案1】:

    有一种称为contracts 的机制,但此功能是实验性的,它的使用必须用@ExperimentalContracts@OptIn(ExperimentalContracts::class) 标记

    @OptIn(ExperimentalContracts::class)
    inline fun <T> stringOpHelper(fn: () -> T) {
        contract {
            callsInPlace(fn, kotlin.contracts.InvocationKind.EXACTLY_ONCE)
        }
        println("performing string operation")
        fn()
    }
    

    【讨论】:

    • 啊,谢谢你分享这个。太糟糕了,它仍然是实验性的
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-11
    • 1970-01-01
    • 2017-01-16
    相关资源
    最近更新 更多