当函数调用作为参数传递给另一个函数时,Kotlin错误地推断出可空枚举返回类型

zpf6vheq  于 7个月前  发布在  Kotlin
关注(0)|答案(1)|浏览(61)

我可能没有很好地解释标题中的问题,但这里有一个例子:

fun main() {
    acceptEnum(inferType())
}

fun acceptEnum(value: MyEnum?) {}

fun <R : Enum<R>?> inferType(): R = TODO()

enum class MyEnum {
    VALUE
}

字符串
inferType()函数推断其返回类型并将其绑定为通用的可空枚举。acceptEnum()函数有一个可空枚举参数。当我们编写acceptEnum(inferType())时,一切都很好。但是如果我们向acceptEnum()添加一个参数并再次传递inferType(),会发生以下情况:

fun main() {
    // first inferType() does not compile with an error:
    // Type mismatch: inferred type is MyEnum? but MyEnum was expected
    acceptEnum(inferType(), inferType())
}

fun acceptEnum(value: MyEnum?, value2: MyEnum?) {}


如果我们添加更多的参数,除了最后一个inferType()调用,每个inferType()调用都会产生这个错误。
这是一个编译器bug还是我做错了什么?

更新

Kotlin论坛帖子:https://discuss.kotlinlang.org/t/kotlin-incorrectly-infers-nullable-enum-return-type-when-a-function-call-is-passed-as-an-argument-to-another-function/23650

更新

Kotlin问题https://youtrack.jetbrains.com/issue/KT-50232

qpgpyjmq

qpgpyjmq1#

这不是一个编译器错误。Enum的类型参数可能不能为空,但您的R是可以为空的。
从Kotlin1.7开始,有一个解决方案。它是definitely non-nullable types。使用这种语法,你的类型定义将变成

fun <R : Enum<R & Any>?> inferType(): R = TODO()

字符串
R & Any保证虽然R是可空的,但Enum的类型参数不是。然后您的代码将在没有警告的情况下编译。

相关问题