【问题标题】:kotlin: extension methods and null receiverkotlin:扩展方法和空接收器
【发布时间】:2018-01-24 17:02:36
【问题描述】:

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

Kotlin 扩展方法是静态解析的,所以我认为它是相同的语法糖。但是当我写的时候

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

我收到关于非空接收器上不必要的安全调用的警告。这是否意味着我不能像 Lombok 那样对空对象调用扩展函数?

【问题讨论】:

    标签: kotlin kotlin-extension


    【解决方案1】:

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

    fun Any?.stringOrNull() = ...
    

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

    【讨论】:

      【解决方案2】:

      您可以在可为空的接收器类型上创建扩展。在您的示例中,它必须是 Any? 而不是 Any 不允许 null,请参阅 docs

      可空接收器

      请注意,可以使用可为空的接收器类型来定义扩展。即使对象变量的值为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()
      }
      

      【讨论】:

        【解决方案3】:

        小心,因为:

        fun Any?.toString(): String
        

        以下行为:

        var obj: Any? = null
        
        obj?.toString() // is actually null
        obj.toString() // returns "null" string
        

        在意识到这一点之前花了 15 分钟非常令人沮丧...

        【讨论】:

          【解决方案4】:

          val 字符串:字符串? =“你好世界!” 打印(字符串。长度)
          // 编译错误:不能直接访问可为空类型的属性。 打印(字符串?。长度)
          // 将打印字符串的长度,如果字符串为空,则打印“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()
          }
          

          【讨论】:

            猜你喜欢
            • 2018-05-26
            • 2020-04-24
            • 1970-01-01
            • 2020-03-03
            • 2016-07-13
            • 2015-03-28
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多