1

Scala で名前による呼び出しパラメーターを使用することについて少し混乱しています。ここで何が起こっているのかを理解するのを手伝ってください。call-by-name パラメーターを使用する次の例を検討してください。

  def param = {println("Param evaluates"); 40}
  def lazyEval(x: => Int) = {
    println("lazy"); 
    x 
  }
  val s = lazyEval(param + 2)
  // s = 42

これについて互いに関連するいくつかの質問があります。

  1. lazyEvalメソッドは type のパラメーターを期待する=> Intのに、なぜparam + 2操作が合法なのですか? メソッドを呼び出すときに=> Int、型を持つオブジェクトに整数 2 を追加できるのはなぜですか? IDEが私に示唆しているように、関数は(一体何?)の代わりに型のパラメータを期待しています。<function0>lazyEvallazyEvalInt=> Int

  2. コールバック タイプを=> Intから() => Intコードに変更した後、コンパイルされないのはなぜですか? これは2種類の違いですか?短いバージョン ('=> Int') は単なる構文糖衣だと思います。

  3. コードでいくつか遊んだ後、最終的にコードを変更して、でコンパイルできるようにしました() => Int。この方法は私にとってより直感的です。

.

  def param = {println("Param evaluates"); 40}
  def lazyEval(x: () => Int) = { // changed type to '() => Int'
    println("lazy"); 
    x() // explicitly calling function using parentheses '()'
  }    
  val s = lazyEval(param _) // adding underscore after method name and removing `+2`

=> Intこのバージョンと最初のバージョン (コールバックタイプあり)の違いは何ですか? 2このバージョンでは、値とparam関数 (つまり this lazyEval(param _ + 2))を使用して整数を加算できないのはなぜですか? そして、メソッド名の後のアンダースコアはどういう意味ですか? (戻り値ではなく、メソッド自体を渡すために使用されていたと思います)

助けてくれてありがとう

4

3 に答える 3

3

では、なぜ param + 2 操作が合法なのですか? type => Int のオブジェクトに整数 2 を追加できる理由

に評価されるため2、に追加できます。は関数ではなく、メソッドなので、そうです。すなわち。に評価される式。paramIntIntIntparam=> Intparam + 2 => IntInt

コールバックの型を => Int から () に変更した後 => Intcode がコンパイルされないのはなぜですか? これは2種類の違いですか?短いバージョン ('=> Int') は単なる構文糖衣だと思います。

=> Int同じ意味ではあり() => Intません。1 つは に評価されるもので、もう 1 つはからまでIntの関数です。ではありませんが、です。または、 is とも言えます。UnitInt2() => Int() => 22=> Int

このバージョンでは、値 2 と param 関数 (thislazyEval(param _ + 2) を意味します) を使用して整数を加算できないのはなぜですか? そして、メソッド名の後のアンダースコアはどういう意味ですか? (戻り値ではなく、メソッド自体を渡すために使用されていたと思います)

param関数ではなくメソッドです。この場合のアンダースコアはparam関数に持ち込まれます。関数param _も同様() => Intです。2関数に追加することはできないので、まさにそれが私たちがそれに追加できない理由です2。基本的に、(1) が機能しないと考える正確な理由です。


要約すれば:

def lazyEval(x: => Int)に評価さxれる任意のパラメーターを持つメソッドです。それは、 を返す任意のメソッド、 の具体的な値、または に解決されるコードのブロックなどである可能性があります。IntIntIntInt

lazyEval(x: () => Int)は、を返すパラメーターなしの関数のみxにすることができるパラメーターを持つメソッドです。これは、関数にリフトされたメソッド、または のような奇妙なものを意味する可能性があります。しかし、それは関数でなければなりません。したがって、次のような値を渡すだけでは機能しません。Intparam() => 22

于 2015-03-22T02:40:18.883 に答える
1

のタイプdef i: Intは次のとおりです。

http://www.scala-lang.org/files/archive/spec/2.11/03-types.html#method-types

名前によるパラメータの型については、i: => Int次で説明します。

http://www.scala-lang.org/files/archive/spec/2.11/04-basic-declarations-and-definitions.html#by-name-parameters

このようなパラメーターの型は、パラメーターのないメソッドの型 => T です。

つまり、メソッド type と同じdef i: Intです。

于 2015-03-22T08:12:50.823 に答える