Scala笔记:def VS val

先说原理:

val修饰的在定义的时候执行

def修饰的在调用的时候执行

直观的例子:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
//注释的行为REPL输出
def test: () => Int = {
    println("def called")
    val r = util.Random.nextInt
    () => r
}
//test: () => Int
test()
//def called
//res82: Int = -950077410

test()
//def called
//res83: Int = 1027028032

val test: () => Int = {
    println("def called")
    val r = util.Random.nextInt
    () => r
}
//def called
//test: () => Int = $$Lambda$1382/338526071@42f2515d

test()
//res84: Int = 300588352
test()
//res84: Int = 300588352

def在方法定义的时候除了新的方法没有任何输出;之后每次调用的时候都会执行一次,而且是每次调用都获得一个新的方法(random值不同)

val在方法定义的时候除了新的方法,还会执行并获得一个方法;之后每次调用都只是执行了定义的时候获得的方法(() => r,r值固定)

进阶

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
def timer[A](f: => A) = {
  def now = System.currentTimeMillis
  val start = now; val a = f; val end = now
  println(s"Executed int ${end - start} ms")
  a
}

val veryRandomAmount = timer {
  util.Random.setSeed(System.currentTimeMillis)
  for (i <- 1 to 100000) util.Random.nextDouble
  util.Random.nextDouble
}

看过上面的例子就不难理解了,重新定义now是为了使用简洁优雅的方式获取当前毫秒数。

  1. val start = now; 用val修饰,记录方法执行前的时间到start中。
  2. val a = f 用val修饰,执行f方法,并保存数据到a中。
  3. val end = now 用vla修饰,记录方法执行结束时间到end中。
  4. 最后返回a,

Comments

comments powered by Disqus