有什么区别:
def even: Int => Boolean = _ % 2 == 0
and
val even: Int => Boolean = _ % 2 == 0
两者都可以称为偶数(10)。
有什么区别:
def even: Int => Boolean = _ % 2 == 0
and
val even: Int => Boolean = _ % 2 == 0
两者都可以称为偶数(10)。
当前回答
看到这个:
var x = 2 // using var as I need to change it to 3 later
val sq = x*x // evaluates right now
x = 3 // no effect! sq is already evaluated
println(sq)
令人惊讶的是,这将打印4而不是9!Val(甚至var)立即计算并分配。 现在将val改为def..它将打印9!Def是一个函数调用。它将在每次调用时求值。
其他回答
此外,Val是一个按值求值。这意味着右边的表达式在定义期间被求值。其中Def是通过名称求值。直到它被使用时才会计算。
在REPL,
scala> def even: Int => Boolean = { _% 2 == 0 }
even: Int => Boolean
scala> val even: Int => Boolean = { _% 2 == 0 }
even: Int => Boolean = $$Lambda$1157/1017502292@57a0aeb8
Def表示按名称调用,按需计算
Val表示在初始化时按值调用
看到这个:
var x = 2 // using var as I need to change it to 3 later
val sq = x*x // evaluates right now
x = 3 // no effect! sq is already evaluated
println(sq)
令人惊讶的是,这将打印4而不是9!Val(甚至var)立即计算并分配。 现在将val改为def..它将打印9!Def是一个函数调用。它将在每次调用时求值。
执行像def x = e这样的定义不会求表达式e的值。相反,每当x被调用时,e都会被求值。
或者,Scala提供了一个值定义 Val x = e,它计算右边的值作为定义值的一部分。 如果随后使用x,则立即用预先计算的e值替换它,这样表达式就不需要再次求值。
考虑一下:
scala> def even: (Int => Boolean) = {
println("def");
(x => x % 2 == 0)
}
even: Int => Boolean
scala> val even2: (Int => Boolean) = {
println("val");
(x => x % 2 == 0)
}
val //gets printed while declaration. line-4
even2: Int => Boolean = <function1>
scala> even(1)
def
res9: Boolean = false
scala> even2(1)
res10: Boolean = false
你看到区别了吗?简而言之:
对于even的每一次调用,它都会再次调用even方法的主体。但是对于even2,即val,函数在声明时只初始化一次(因此它在第4行打印val,再也不打印了),并且每次访问都使用相同的输出。例如,试着这样做:
scala> import scala.util.Random
import scala.util.Random
scala> val x = { Random.nextInt }
x: Int = -1307706866
scala> x
res0: Int = -1307706866
scala> x
res1: Int = -1307706866
当x被初始化时,由Random返回的值。nextInt被设置为x的最终值。下一次再次使用x时,它总是返回相同的值。
你也可以惰性初始化x,即第一次使用它时,它是初始化的,而不是在声明时。例如:
scala> lazy val y = { Random.nextInt }
y: Int = <lazy>
scala> y
res4: Int = 323930673
scala> y
res5: Int = 323930673