【问题标题】:Why must class member function types be called with invoke?为什么必须用invoke调用类成员函数类型?
【发布时间】:2018-01-08 19:51:51
【问题描述】:
fun test() {
    class Test(val foo: ((Double, Double) -> Double)?)
    val test = Test(null)

    if(test.foo != null) test.foo(1.0, 2.0)
}

上面的代码产生了错误:

Kotlin:引用具有可为空的类型 '((Double, Double) -> DoubleArray)?',使用显式 '?.invoke()' 进行类似函数的调用 而是。

如果我遵循错误建议并将调用更改为 test.foo?.invoke(1.0, 2.0),代码会编译,但 IntelliJ 现在会报告

对 '((Double, Double) -> DoubleArray) 类型的非空接收器进行不必要的安全调用

按照这个建议,我最终得到了 test.foo.invoke(1.0, 2.0),我认为它可以与 test.foo(1.0, 2.0) 互换;为什么这里不是这样?

当 foo 不是类成员时,一切正常:

fun test2() {
    val foo: ((Double, Double) -> Double)? = null

    if(foo != null) foo(1.0, 2.0)
}

【问题讨论】:

  • 这看起来像一个错误。如果 kotl.in/issue 尚不存在,您可以创建一个问题。

标签: kotlin


【解决方案1】:

有一个未解决的问题:https://youtrack.jetbrains.com/issue/KT-4113

目前,它的目标版本是 1.3。

【讨论】:

  • 好发现!在我最初的搜索中没有出现。
  • 在我找到它之前,它有些挖掘。感谢您确认这是一个错误,而不仅仅是 Kotlin 的一些怪癖!
  • 太糟糕了,这个问题已经 8 年了,它仍然是开放的。
【解决方案2】:

smart casting 在这种情况下似乎不能正常工作,我希望和你一样。它仅适用于invoke()

我的解决方法将改用let

test.foo?.let { foo ->
    foo(1.0, 2.0)
}

【讨论】:

    猜你喜欢
    • 2020-10-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-31
    • 2021-09-02
    相关资源
    最近更新 更多