【问题标题】:Kotlin - get the non-nullable inference of a nullable generic type inferenceKotlin - 获取可空泛型类型推断的不可空推断
【发布时间】:2018-06-07 21:44:52
【问题描述】:

我想知道是否可以强制 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 &lt;O, P&gt; wrap(property: KProperty1&lt;O, P&gt;, wrapper: Wrapper&lt;P&gt;): Unit

以下没有替换

(KProperty1&lt;NullableExample, String&gt;, Wrapper&lt;String&gt;)

(KProperty1&lt;NullableExample, String?&gt;, Wrapper&lt;String?&gt;)

可应用于

(KProperty1&lt;NullableExample, String?&gt;, StringWrapper)

所以基本上我想要的是,不管P 是可空的还是不可空的,Wrapper&lt;P&gt;P 应该始终是P 的不可空形式。这可能吗?

【问题讨论】:

  • 你能从value 定义一个派生属性,但不能为空,并在调用wrap 时执行NullableExample::NonNullableValue 吗?当然你需要处理valuenull 时会发生什么,但无论如何你都需要在某个地方处理它,对吧?

标签: kotlin


【解决方案1】:

所以基本上我想要的是,不管P 是可空的还是不可空的,Wrapper&lt;P&gt;P 应该始终是P 的不可空形式。

如上所述,这不太合理:P 只有一个,Wrapper&lt;P&gt;KProperty1&lt;O, P&gt; 中没有单独的一个。所以如果你想让它们不同,你不能同时使用P

但是KProperty1 在结果类型中是协变的,所以KProperty1&lt;O, P&gt; 也是KProperty1&lt;O, P?&gt;。因此,如果您将签名更改为

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

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

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

【讨论】:

    猜你喜欢
    • 2021-02-17
    • 1970-01-01
    • 2018-05-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多