Kotlin 自定义作用域函数返回类型未按预期运行

标签 kotlin generics lambda scope

此自定义函数调用为 null 时的 lambda block 。 我希望下面的函数定义强制执行相同的返回类型。 :T
他们是一种强制执行 block 返回类型 T 的方法吗?

inline fun <T> T?.whenNull(block: () -> T): T {
    if (this == null) {
        return block() //accepts any return type
    } else {
        return this
    }
}

fun main() {
    val x : Int? = null
    println(x ?: 42)
    println(x.whenNull { 42 })
    println(x.whenNull { "why is kotlin not enforcing return of the same type?" })
}

最佳答案

第二个 whenAll 调用中的

T 被推断为 Any。想象一下,所有出现的 T 都被替换为 Any,调用将是有效的,你不同意吗?毕竟,IntString 都是 Any 的子类型。

inline fun Any?.whenNull(block: () -> Any): Any {
    if (this == null) {
        return block()
    } else {
        return this
    }
}

fun main() {
    println(x.whenNull { "why is kotlin not enforcing return of the same type?" })
}

基本上,Kotlin 编译器在这里“太过努力”以编译您的代码,并为您的类型参数推断出意外的类型。


存在一个内部注释@kotlin.internal.InputTypesOnly如果函数的一种输入类型(参数类型、接收者类型等)中未提及推断的类型,这将阻止您的代码编译。

在这种情况下,输入类型只是 Int?,而 T 被推断为 Any,所以它会让你的代码未按预期编译。不幸的是,这个注释是内部的,你不能使用它:( KT-13198 是关于公开它的门票。

关于Kotlin 自定义作用域函数返回类型未按预期运行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72668828/

相关文章:

python - 使用可变泛型进行方法返回专门化

vb.net - LINQ 查询到 LINQ 方法;为什么我需要CBool​​?

c# - 创建要应用于 IQueryable 的动态搜索的最简单方法

gradle - 如何为kotlin2JS插件设置gradle outout文件夹?

android - 在 Jetpack Compose 中设置负填充值的替代解决方案? (java.lang.IllegalArgumentException : Padding must be non-negative)

md5 - DigestUtils.md5Hex() 传递 String 对象时生成错误的哈希值

python - 如何将 View 方法转换为通用 ListView ?

c# - 使用 Linq 比较两个通用列表

java - Kotlin 中的新运算符(语法)

java - Lambda 不会覆盖单独文件中的接口(interface)方法