首页 > 解决方案 > Kotlin - 获取可空泛型类型推断的不可空推断

问题描述

我想知道是否可以强制 kotlin 推断给定类型推断的不可为空。考虑以下示例:

abstract class Wrapper<T>
class StringWrapper : Wrapper<String>()

fun <O, P> wrap(property: KProperty1<O, P>, wrapper: Wrapper<P>) {

}

当我调用wrap不可为空的属性时,一切正常:

data class NonNullableExample(val value: String)
wrap(NonNullableExample::value, StringWrapper())

但是当我调用wrap一个可以为空的属性时,我得到一个编译器错误,因为推断是P可以为空的,而StringWrapper不是:

data class NullableExample(val value: String?)
wrap(NullableExample::value, StringWrapper())

P类型推断失败:无法推断类型参数

fun <O, P> wrap(property: KProperty1<O, P>, wrapper: Wrapper<P>): Unit

以下替换均无

(KProperty1<NullableExample, String>, Wrapper<String>)

(KProperty1<NullableExample, String?>, Wrapper<String?>)

可以应用于

(KProperty1<NullableExample, String?>, StringWrapper)

所以基本上我想要的是,无论P是可空的还是不可空的,PofWrapper<P>应该始终是不可空的P. 这可能吗?

标签: kotlin

解决方案


所以基本上我想要的是,无论P是可空的还是不可空的,PofWrapper<P>应该始终是不可空的P.

如前所述,这不太有意义: and 中只有一个,P而不是单独的一个。因此,如果您希望它们有所不同,则不能同时使用它们。Wrapper<P>KProperty1<O, P>P

但是KProperty1在结果类型中是协变的,所以 aKProperty1<O, P>也是 a KProperty1<O, P?>。因此,如果您将签名更改为

fun <O, P : Any> wrap(property: KProperty1<O, P?>, wrapper: Wrapper<P>): Unit

它将接受可为空和不可为空的属性:

wrap(NonNullableExample::value, StringWrapper())
wrap(NullableExample::value, StringWrapper())
// both compile

推荐阅读