13

我知道这已经在其他帖子中讨论过,并且我了解使用def和之间的基本区别valdef用于定义方法和val不可变引用。通过提出这个问题,我试图完成的是了解是否还有更多内容def。可以和a互换使用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来声明和初始化变量吗?

4

3 回答 3

11

两个都

def i = 3

def i() = 3

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

于 2012-10-08T18:55:11.703 回答
7

defval如您所知,定义一个方法,定义一个不可变值。

一个主要区别在于计算右侧的表达式的时间=。对于方法,每次调用该方法时都会对其进行评估。对于一个值,它会在您初始化该值时进行评估。看到不同:

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
于 2012-10-09T07:39:34.313 回答
6

只是为了添加金的答案,您可以通过 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
于 2012-10-08T21:45:23.423 回答