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

Dom*_*kis 4 scala

遵循两个类似的功能,a并以b不同的方式声明:

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

scala> def b(x:Int) = x+x
b: (x: Int)Int
Run Code Online (Sandbox Code Playgroud)

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

编辑:

我也无法@tailrecval方法中使用注释.

Nik*_*kov 8

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

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

1.to(4).map(b)
Run Code Online (Sandbox Code Playgroud)

desugars到包装lambda:

1.to(4).map((x: Int) => b(x))
Run Code Online (Sandbox Code Playgroud)

这本身就是一种糖:

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

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