【问题标题】:Kotlin 1.3.61 fails to resolve return type of extension property on function literalKotlin 1.3.61 无法解析函数文字上扩展属性的返回类型
【发布时间】:2020-01-30 13:11:08
【问题描述】:

在下面的示例中,我编写了简单的装饰器扩展,它可以捕获异常并在任何错误时返回 null。问题是num1num2 类型被推断为R? 而不是Double?

val <R> (()->R).nothrow: (()->R?) get() = { try { invoke() } catch(ex: Throwable) { null } }

fun main() {
  val num1 = "42"::toDouble.nothrow()
  println(num1)
  val num2 = "english"::toDouble.nothrow()
  println(num2)
}

程序输出为:

42.0
null

但是当我写的时候

num1!! + 3.14

我得到错误:

Unresolved reference. None of the following candidates is applicable because of receiver type mismatch

候选人都是plus存在的运营商。

nothrow扩展的反编译java代码如下:

@NotNull
public static final Function0 getNothrow(@NotNull Function0 $this$nothrow) {
    int $i$f$getNothrow = 0;
    Intrinsics.checkParameterIsNotNull($this$nothrow, "$this$nothrow");
    return (Function0)(new Function0($this$nothrow) {
       // $FF: synthetic field
       final Function0 $this_nothrow;

       @Nullable
       public final Object invoke() {
          Object var1;
          try {
             var1 = this.$this_nothrow.invoke();
          } catch (Throwable var3) {
             var1 = null;
          }

          return var1;
       }

       public {
          this.$this_nothrow = var1;
       }
    });
 }

为什么会这样?


编辑

问题似乎出在扩展属性上:

【问题讨论】:

    标签: java generics kotlin extension-methods


    【解决方案1】:

    如果你在你调用的函数周围加上括号,它是固定的:

    val num1 = ("42"::toDouble.nothrow)()
    println(num1)
    val num2 = ("english"::toDouble.nothrow)()
    println(num2)
    num1!! + 3.14 // Does not fail
    

    如果您尝试在 IDEA 中编写此代码:

    "42"::toDouble()
    

    上面写着:

    此语法保留供将来使用;要调用引用,请将其括在括号中:(foo::bar)(args)

    这就是您的代码失败的原因。你的代码比仅仅调用一个引用更棘手,所以 IDEA 无法检测到它。

    【讨论】:

    • 嗯,这很有趣。虽然我不使用::abc() 语法,但将方法引用作为扩展函数的接收者传递。它应该与将方法引用作为参数传递给普通函数一样,不是吗?
    • 是的,你是对的,即使我们用类似类型的 lambda 替换方法引用,这个问题仍然存在。它看起来像一个错误,因为 IDEA 说 "42"::toDouble.nothrow() 的类型是 R?,尽管我们仍然在没有任何泛型的 main 函数中。无论如何,调用函数类型的属性和调用函数具有相似的语法,因此它甚至可能是预期的行为(调用函数而不是调用函数属性,因为可以通过括号达到第二个),所以你应该使用括号(或写@ 987654327@ 明确)。
    • 嗯,这不是很令人振奋 :D 我想避免样板代码。
    • 我不认为一对括号(必要时)是样板代码
    • 好吧,在简单的场景中它不是,但我仍然对连续类型转换感到噩梦
    猜你喜欢
    • 1970-01-01
    • 2021-11-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-17
    • 1970-01-01
    相关资源
    最近更新 更多