我想知道是否有可能强制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>
的不可空形式。这可能吗?
答案 0 :(得分:1)
基本上我想要的是,无论
P
是可空的还是不可空的,P
的{{1}}都应该始终是Wrapper<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