代码之家  ›  专栏  ›  技术社区  ›  y.allam

Kotlin:为什么我不能在变量中存储函数?

  •  4
  • y.allam  · 技术社区  · 6 年前

    为什么必须使用函数引用将函数存储到变量中:

    fun someFunction(i: Int): Unit = println(i)
    val funVal = someFunction  // Compile error!
    val funVal2 = ::someFunction // Function reference works fine
    

    但我可以直接将lambda存储在变量中:

    val someLambda: (Int) -> Unit = { i: Int -> println(i) }
    
    3 回复  |  直到 6 年前
        1
  •  4
  •   GhostCat    6 年前

    这是关于正确的语法。或者更准确地说,关于编译器 理解 你想说什么!

    当您查看不同的示例时,您会发现接受的案例使用特定的字符,例如冒号。这使得推断代码的含义变得简单。

    所以,一个可能的原因是权衡。当然,如果有的话

    val a = b
    

    您可以允许b作为方法引用。但是如果你想改为调用b()呢?!b和b()之间的“词典”距离非常小!

    因此,为了不允许这种语法,a)更容易解析代码,b)更难让小的打字错误改变代码的含义!

        2
  •  2
  •   hotkey    6 年前

    这个 GhostCat's answer 是非常正确的,但它遗漏了一个重要的点,我认为应该提到这一点来完成它。

    可调用引用语法在函数和属性之间是一致的,但在属性的情况下,必须区分属性访问 foo 从其可调用引用 ::foo .

    val foo: Int = TODO()
    val fooValue = foo
    val fooReference = ::foo
    

    所以,当函数实际上 能够 只使用函数名获取可调用引用语法 (函数调用不含糊 foo() 无论如何),为了一致性,函数共享可调用的引用语法。 :福奥 而属性则需要一些特殊的可调用引用的语法形式。

        3
  •  0
  •   Omar Mainegra    6 年前

    因为 fun someFunction(i: Int): Unit = println(i) 尽管是一个 function 更具体的类型是 method ,这就是您需要方法引用语法的原因。某物 similar 发生在 Scala

    例子

    fun method(value: String) = println(value)
    val function: (String) -> Unit = { value -> println(value) }
    
    val methodRef = ::method
    val functionRef = function
    

    进一步阅读 “Kotlin编程器词典”