这是def和val之间差异的有效定义吗?

时间:2015-03-12 09:58:02

标签: scala

Scala编译器不会评估方法,只是确定其参数和返回类型。 Scala编译器评估分配。

我将这些陈述基于以下陈述的评估:

    //create a function which accepts two int parameters and returns their sum
  def f(a: Int, b: Int) = a + b                   //> f: (a: Int, b: Int)Int

  //create a function which returns the sum of 1+2
  def fh = f(1, 2)                                //> fh: => Int

  //The use of val forces the function 'f' to be evaluated :
  val vh = f(1, 2)                                //> vh  : Int = 3

2 个答案:

答案 0 :(得分:2)

让我们看一下以下控制台输出:

scala> def f(a:Int, b:Int) = {
     | println("f called...")
     | a+b
     | }
f: (a: Int, b: Int)Int

scala> f(1,2)
f called...
res4: Int = 3

我略微修改了函数定义。现在,当我们调用f时,它会打印出f called...

scala> def fh = f(1,2)
fh: Int

scala> fh
f called...
res5: Int = 3

当您键入fh并按Enter键时,fh将执行f(1,2)。您可以看到控制台上打印了f called...。每当评估fh时,屏幕上都会显示f called...

scala> val vh = f(1,2)
f called...
vh: Int = 3

scala> vh
res6: Int = 3

当您键入vh时,它不会打印出消息。有什么区别? fh只是f(1,2)的别名,在评估f时会调用fh。另一方面,vh只是使用f(1,2)的结果初始化的值。

答案 1 :(得分:0)

简而言之:

    每次访问 时,都会对
  • def进行评估
  • val仅在第一次遇到
  • 时进行评估
  • 还有第三种类型的声明lazy val,仅在第一次使用时进行评估 - 如果它没有抛出异常,否则会重新评估

这最后一点并不为人所知,因为大多数人认为lazy val仅在第一次被评估时才会被评估为无例外。以下示例演示了它:

scala> var n = 1  
n: Int = 1

scala> lazy val x = if (n == 1) sys.error("Not Ready") else 42  
x: Int = <lazy>

scala> x  
java.lang.RuntimeException: Not Ready  
...

scala> n = 0  
n: Int = 0

scala> x  
res1: Int = 42

scala> n = 1
n: Int = 1

scala> x  
res2: Int = 42