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

时间:2018-06-06 22:11:07

标签: 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是可空的还是不可空的,P的{​​{1}}都应该始终是Wrapper<P>的不可空形式。这可能吗?

1 个答案:

答案 0 :(得分:1)

  

基本上我想要的是,无论P是可空的还是不可空的,P的{​​{1}}都应该始终是Wrapper<P>的不可空形式。

如上所述,这没有多大意义:只有一个P,而不是PWrapper<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