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

ila*_*ngo 13 scala

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

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

scala> def i: Int = 3
i: Int

scala> i
res2: Int = 3
Run Code Online (Sandbox Code Playgroud)

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

然后我尝试了这个:

scala> i()
<console>:9: error: Int does not take parameters
i()
Run Code Online (Sandbox Code Playgroud)

我这样做只是为了测试我对语义​​的理解def.现在我想知道,何时i是一种方法,为什么Scala抱怨"......不带参数"?

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

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

scala> i()
res4: Int = 3
Run Code Online (Sandbox Code Playgroud)

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

Kim*_*bel 11

def i = 3
Run Code Online (Sandbox Code Playgroud)

def i() = 3
Run Code Online (Sandbox Code Playgroud)

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

  • 你可以调用一个用`()`声明的方法而不用括号,但是你不能调用一个没有圆括号括号的声明的方法. (3认同)

Jes*_*per 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
Run Code Online (Sandbox Code Playgroud)


小智 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
Run Code Online (Sandbox Code Playgroud)