这是 def 和 val 之间区别的有效定义吗?



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

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

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并按 输入 键, 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)的别名,它将在评估fh时调用f。另一方面,vh只是一个用 f(1,2) 的结果初始化的值。

简而言之:

  • 每次访问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

相关内容

  • 没有找到相关文章

最新更新