kotlin:扩展方法和null接收器

时间:2018-01-24 17:02:36

标签: kotlin kotlin-extension

在lombok扩展方法中,obj.method()SomeUtil.method(obj)的语法糖。它允许obj为空。

Kotlin扩展方法是静态解决的,所以我假设它是相同的语法糖,当我写

fun Any.stringOrNull() = this?.toString()

我收到有关非空接收器上不必要的安全呼叫的警告。这是否意味着我无法像使用lombok一样调用null对象上的扩展函数?

4 个答案:

答案 0 :(得分:9)

如果您将其定义为可空类型的扩展名,则可以在可空对象上调用它:

fun Any?.stringOrNull() = ...

否则,与任何其他方法一样,您必须使用safe call operator

答案 1 :(得分:3)

除了给定的答案,请参阅docs

  

Nullable Receiver

     

请注意,可以使用可为空的接收器类型定义扩展。即使对象变量的值为null,也可以在对象变量上调用此类扩展,并且可以检查正文内的this == null。这使您可以在Kotlin中调用toString()而无需检查null:检查发生在扩展函数内。

fun Any?.toString(): String {
    if (this == null) return "null"
    // after the null check, 'this' is autocast to a non-null type, so the toString() below
    // resolves to the member function of the Any class
    return toString()
}

答案 2 :(得分:0)

val字符串:字符串? =“世界你好!” 打印(string.length)
//编译错误:无法直接访问可为null的属性。 打印(字符串?。长度)
//将打印字符串的长度,如果字符串为null,则为“ null”。

?.安全呼叫运算符,用于可为空的接收器##

如果左侧的值为null,则安全调用运算符将​​返回null,否则继续评估右侧的表达式,因此为了在可为null的接收器上调用任何函数,您需要在Any之后使用安全调用运算符。任何?) 然后,您可以在函数体内检查this(此处为this object points to receiver)的null值。这就是您可以在Kotlin中调用toString()而不检查null的原因:检查发生在扩展函数内部。

fun Any?.toString(): String {
    if (this == null) return "null"
    // after the null check, 'this' is autocast to a non-null type, so the toString() below
    // resolves to the member function of the Any class
    return toString()
}

答案 3 :(得分:0)

注意:

fun Any?.toString(): String

以下行为:

var obj: Any? = null

obj?.toString() // is actually null
obj.toString() // returns "null" string

才花了15分钟,这让我很沮丧……