代码之家  ›  专栏  ›  技术社区  ›  Antti Vikman

为什么在Scala中定义的没有空括号的函数的行为不像函数?

  •  3
  • Antti Vikman  · 技术社区  · 11 年前

    考虑以下2个对象

    object TestObj1 {
      def testMethod = "Some text"
    }
    
    object TestObj2 {
      def testMethod() = "Some text"
    }
    

    如果我直接调用这些方法,它们会按照我的期望执行

    scala> TestObj1.testMethod
    res1: String = Some text
    
    scala> TestObj2.testMethod
    res2: String = Some text
    

    但现在如果我们定义以下函数

    def functionTakingFunction(callback: () => String) {
      println("Call returns: " + callback())
    } 
    

    并且尝试调用它时,不接受不带()定义的方法。

    scala> functionTakingFunction(TestObj1.testMethod)
    <console>:10: error: type mismatch;
     found   : String
     required: () => String
                  functionTakingFunction(TestObj1.testMethod)
                                                  ^
    
    scala> functionTakingFunction(TestObj2.testMethod)
    Call returns: Some text
    

    我还注意到,不能使用括号调用TestObj1.testMethod,因为它已经是一个String了。但是什么导致了这种行为?

    3 回复  |  直到 11 年前
        1
  •  9
  •   corazza    10 年前

    您不是在传递方法,而是在调用它,然后将其结果传递到调用中。

    如果你想传递这个方法,你首先必须把它转换成一个函数,然后传递:

    functionTakingFunction(TestObj1.testMethod _)
    

    给你 testMethod 转换为 部分应用 函数(称为“绑定”)。

    你必须这么做的原因是 TestObj1.testMethod 不评估为 function0 (需要传递给 functionTakingFunction ),但对 String 因为它的声明方式(没有括号)。

    它在 TestObj2 因为testMethod是用括号定义的,因此只需键入 TestObj2.testMethod 不调用它。

        2
  •  0
  •   monnef    11 年前

    functionTakingFunction(TestObj1.testFunction) 称为 functionTakingFunction("Some text") -它是经过评估而不是通过的

        3
  •  -1
  •   Sudipta Deb    11 年前

    在这里,您没有传递函数。你要做的是评估 TestObj1.testFunction 然后将结果传递给 functionTakingFunction 但如果你看到函数TakingFunction的定义,它清楚地表明

    def functionTakingFunction(callback: () => String)
    

    表示此函数需要一个返回类型为单位的函数。但是 测试对象1.测试函数 没有返回类型。

    单元退货类型和无退货类型之间的区别是:

    • 无返回类型意味着此方法不会返回任何内容
    • 单位返回类型意味着此方法将返回没有意义值的东西。

    希望现在对你有帮助。快乐的编码,享受Scala。