给出表达相同函数的三种方式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>
答案 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
。)
f3
与f2
相同。你只是不在那里使用类型推断。
答案 2 :(得分:3)
执行 def x = e 等定义不会评估表达式 e 。每当使用 x 时,都会评估 e 。或者,Scala提供值定义 val x = e ,评估右侧 e 作为评估的一部分 定义。如果随后使用 x ,则立即将其替换为 e 的预先计算值,因此无需再次计算表达式。
Scala示例 通过 Martin Odersky