这两种声明函数的方法有什么区别?

时间:2014-06-01 10:32:10

标签: scala

遵循两个类似的功能,ab,声明不同:

scala> val a = { x:Int => x+x }
a: Int => Int = <function1>

scala> def b(x:Int) = x+x
b: (x: Int)Int

我可以在两者之间找到的唯一区别是,只有使用def函数,我可以在传递参数时指定参数的名称(例如b(x=1))。这些功能在其他方面有何不同?什么时候应该使用?

编辑:

我也无法使用@tailrec方法使用val注释。

2 个答案:

答案 0 :(得分:8)

主要区别在于Scala如何翻译这些定义。在Scala中,lambda(匿名函数,函数值,函数文字)和方法是不同的东西。你的第一个定义是一个Function1类实例的糖,它是用于lambdas的类之一,第二个只是周围对象的一个​​方法,它编译成标准的Java方法。 / p>

两者之间的实际区别在于Scala不能仅仅让您将方法称为值,这使得它成为二等公民。在处理更高阶函数时,这会导致冗余的间接。例如,以下内容:

1.to(4).map(b)

desugars到一个包装器lambda:

1.to(4).map((x: Int) => b(x))

本身就是糖:

1.to(4).map(
  new Function1[Int, Int] {
    def apply(x: Int): Int = b(x)
  }
)

感觉非常冗余,对吧?这就是为什么如果你对函数的意图是将它用作一等公民(即,作为值传递),从一开始就将它声明为lambda更为合理。

答案 1 :(得分:2)

简短的回答是:第二个不是一个函数,它是一种方法。这两者根本不同。函数是对象,方法不是(方法属于对象)。