在Scala中定义函数的这三种方式之间的差异

时间:2010-09-05 16:14:36

标签: scala

给出表达相同函数的三种方式f(a) := a + 1

val f1 = (a:Int) => a + 1
def f2 = (a:Int) => a + 1
def f3:(Int => Int) = a => a + 1

这些定义有何不同? REPL没有表明任何明显的差异:

scala> f1
res38: (Int) => Int = <function1>
scala> f2
res39: (Int) => Int = <function1>
scala> f3
res40: (Int) => Int = <function1>

3 个答案:

答案 0 :(得分:122)

在一个类中,val在初始化时进行评估,而def仅在和每次调用该函数时进行评估。在下面的代码中,您将看到x是在第一次使用对象时计算的,但在访问x成员时不会再次计算。相反,在实例化对象时不评估y,而是在每次访问成员时评估y。

  class A(a: Int) {
    val x = { println("x is set to something"); a }
    def y = { println("y is set to something"); a }
  }

  // Prints: x is set to something
  val a = new A(1)

  // Prints: "1"
  println(a.x)

  // Prints: "1"                               
  println(a.x)

  // Prints: "y is set to something" and "1"                                  
  println(a.y)

  // Prints: "y is set to something" and "1"                                                                                   
  println(a.y)

答案 1 :(得分:112)

f1是一个取整数并返回整数的函数。

f2是一个零arity的方法,它返回一个取整数并返回整数的函数。 (稍后在REPL处键入f2时,它将调用方法f2。)

f3f2相同。你只是不在那里使用类型推断。

答案 2 :(得分:3)

执行 def x = e 等定义不会评估表达式 e 。每当使用 x 时,都会评估 e 。或者,Scala提供值定义 val x = e ,评估右侧 e 作为评估的一部分 定义。如果随后使用 x ,则立即将其替换为 e 的预先计算值,因此无需再次计算表达式。

  

Scala示例   通过 Martin Odersky