首页 文章

Kotlin - 获得可空的泛型类型推断的非可空推理

提问于
浏览
2

我想知道是否有可能强迫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 in 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 是可空的还是不可空的, Wrapper<P>Wrapper<P> 应该始终是 P 的非可空形式 . 这可能吗?

1 回答

  • 1

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

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

    但是 KProperty1 在结果类型中是协变的,所以 KProperty1<O, P> 也是 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
    

相关问题