为什么在Scala中使用def和val,反之亦然

时间:2012-10-08 18:50:02

标签: scala

我知道之前在其他帖子中已经讨论了这个问题,我理解使用defval之间的基本区别。 def用于定义方法,val用于不可变引用。我想通过提出这个问题来实现的目的是了解def是否还有更多内容。可以与val交替使用吗?

最近我尝试了以下代码,如果我目前对def的理解是充分的话,就无法说服自己:

scala> def i: Int = 3
i: Int

scala> i
res2: Int = 3

所以我很好奇,这相当于val i = 3

然后我尝试了这个:

scala> i()
<console>:9: error: Int does not take parameters
i()

我这样做只是为了测试我对def语义的理解。现在我想知道,当i是一种方法时,为什么Scala抱怨“......不接受参数”?

接下来我尝试了以下内容:

scala> def i(): Int = 3
i: ()Int

scala> i()
res4: Int = 3

这次Scala似乎同意i是一种方法。那么我可以使用def代替val可互换来声明和初始化变量吗?

3 个答案:

答案 0 :(得分:11)

两个

def i = 3

def i() = 3

声明方法。唯一的区别是,第一个是没有参数列表的方法,第二个是带有空参数列表的方法。前者通常用于没有副作用的方法,后者用于有副作用的方法。 如果值永远不会改变,您应该使用val而不是def,并且您希望避免重新计算它。每次调用def时都会重新计算def,而val只被赋值一次。

答案 1 :(得分:7)

def定义了一个方法,val定义了一个不可变的值,如您所知。

一个主要区别在于评估=右侧的表达式。对于方法,每次调用方法时都会对其进行评估。对于值,在初始化值时会对其进行评估。看到差异:

scala> def i: Int = { println("Hello"); 3 }
i: Int

scala> i
Hello
res0: Int = 3

scala> i
Hello
res1: Int = 3

scala> val i: Int = { println("Hello"); 3 }
Hello
i: Int = 3

scala> i
res2: Int = 3

答案 2 :(得分:6)

只是在Kim的答案的顶部添加,你可以用val覆盖def。

// Entering paste mode (Ctrl+D to finish)

trait A {
  def i: Int
  def num: Long
}

class B extends A {
  val i = 7
  val num = 20L
}

// Exiting paste mode, now interpreting.

defined trait A
defined class B

scala> val b = new B
b: B = B@2d62bdd8

scala> b.i
res1: Int = 7

scala> b.num
res2: Long = 20