13

defこれは SO の他の投稿で以前に議論されたことを知っており、との使用の基本的な違いを理解していますvaldefメソッドの定義と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

4

3 に答える 3

11

両方

def i = 3

def i() = 3

メソッドを宣言します。唯一の違いは、最初のメソッドがパラメーター リストのないメソッドであり、2 番目のメソッドが空のパラメーター リストを持つメソッドであることです。通常、前者は副作用のないメソッドに使用され、後者は副作用のあるメソッドに使用されます。値が決して変わらず、再計算を避けたい場合は、def の代わりに val を使用する必要があります。def は呼び出されるたびに再計算されますが、val は一度だけ値が割り当てられます。

于 2012-10-08T18:55:11.703 に答える
7

defvalすでにご存知のように、メソッドを定義し、不変の値を定義します。

大きな違いの 1 つは、 の右側の式がいつ=評価されるかです。メソッドの場合、メソッドを呼び出すたびに評価されます。値の場合、値を初期化するときに評価されます。違いを見ます:

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 に答える