メソッドパラメータの宣言とは正確にはどういう意味ですか。
def myFunc(param: => Int) = param
上の定義の=>
の意味は何ですか?
これは、いわゆるpass-by-nameです。これは、Int
を返す必要がある関数を渡していることを意味しますが、主にパラメーターの遅延評価を実装するために使用されます。それはやや似ています:
_def myFunc(param: () => Int) = param
_
例を示します。いくつかのanswer
値を返すInt
関数について考えてみましょう。
_def answer = { println("answer"); 40 }
_
そして、2つの関数、1つはInt
を取り、もう1つはInt
を取りますby-name:
_def eagerEval(x: Int) = { println("eager"); x; }
def lazyEval(x: => Int) = { println("lazy"); x; }
_
次に、answer
を使用して両方を実行します。
_eagerEval(answer + 2)
> answer
> eager
lazyEval(answer + 2)
> lazy
> answer
_
最初のケースは明らかです。呼び出す前にeagerEval()
answer
が評価され、_"answer"
_文字列を出力します。 2番目のケースははるかに興味深いものです。実際には、関数をlazyEval()
に渡します。 lazyEval
は最初に_"lazy"
_を出力し、x
パラメータを評価します(実際には、パラメータとして渡されたx
関数を呼び出します)。
Scala言語仕様では、用語call-by-nameを使用しています:
値パラメータのタイプは、=>でプレフィックスを付けることができます。 x:=> T。そのようなパラメーターのタイプは、パラメーターのないメソッドタイプ=> Tです。これは、対応する引数が関数の適用時に評価されるのではなく、関数内で使用されるたびに評価されることを示しています。つまり、引数はcall-by-nameを使用して評価されます。
上記のTomasz Nurkiewiczの答えに追加すると、()=> Intと=> Intの間で私が遭遇する違いは、2番目がベアブロックでの呼び出しを許可することです。
scala> def myfunc(f : () => Int ) = println("Evaluated: " + f )
myfunc: (f: () => Int)Unit
scala> def myfunc2(f : => Int ) = println("Evaluated: " + f )
myfunc2: (f: => Int)Unit
scala> myfunc({1})
<console>:9: error: type mismatch;
found : Int(1)
required: () => Int
myfunc({1})
^
scala> myfunc2({1})
Evaluated: 1