当函数调用作为参数传递给另一个函数时,Kotlin 错误地推断可为 null 的 Enum 返回类型

问题描述 投票:0回答:1

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

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()
调用都会产生此错误。

这是编译器错误还是我做错了什么?

更新

Kotlin 论坛帖子:https://discuss.kotlinlang.org/t/kotlin-in Correctly-infers-nullable-enum-return-type-when-a-function-call-is-passed-as-an-argument-到另一个功能/23650

更新

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

kotlin generics enums type-inference
1个回答
0
投票

这不是编译器错误。

Enum
的类型参数可能不可为空,但您的
R
可以为空。

从 Kotlin 1.7 开始,有一个解决方案。它是“绝对不可为空的类型”。 使用这个语法你的类型定义将变成 fun <R : Enum<R & Any>?> inferType(): R = TODO()

R & Any

保证虽然

R
可以为空,但
Enum
的类型参数却不能为空。然后您的代码将在没有警告的情况下编译。
    

© www.soinside.com 2019 - 2024. All rights reserved.