我知道之前在其他帖子中已经讨论了这个问题,我理解使用def
和val
之间的基本区别。 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
可互换来声明和初始化变量吗?
答案 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