1. ホーム
  2. スカラ

[解決済み】Scalaの名前による呼び出しと値による呼び出し、明確化の必要性

2022-04-16 12:29:17

質問

私の理解では、Scalaでは、関数は次のどちらかを呼び出すことができます。

  • 値によって、または
  • 名前別

例えば、次のような宣言があったとして、その関数がどのように呼び出されるかがわかるでしょうか。

宣言してください。

def  f (x:Int, y:Int) = x;

コール

f (1,2)
f (23+55,5)
f (12+3, 44*11)

ルールを教えてください。

解決方法は?

あなたが挙げた例はcall-by-valueを使用しているだけなので、違いを示す新しい、より単純な例を挙げます。

まず、副作用のある関数があるとします。 この関数は何かをプリントアウトして Int .

def something() = {
  println("calling something")
  1 // return value
}

を受け取る関数を2つ定義します。 Int の引数は、一方がコール・バイ・バリュー方式で引数を取る以外は全く同じものです ( x: Int )、もう一方は名前による呼び出しスタイル( x: => Int ).

def callByValue(x: Int) = {
  println("x1=" + x)
  println("x2=" + x)
}

def callByName(x: => Int) = {
  println("x1=" + x)
  println("x2=" + x)
}

では、副作用のある関数でそれらを呼び出すとどうなるでしょうか。

scala> callByValue(something())
calling something
x1=1
x2=1

scala> callByName(something())
calling something
x1=1
calling something
x2=1

つまり、call-by-valueバージョンでは、渡された関数呼び出しの副作用( something() ) は一度だけ発生しました。 しかし、call-by-nameバージョンでは、副作用は2回起こりました。

これは、コール・バイ・バリュー関数が、渡された式の値を計算してから関数を呼び出すためで、そのため 同じ の値が毎回アクセスされる。 その代わり、名前による呼び出し関数 再計算 は、渡された式の値がアクセスされるたびに、その値を変更します。