27

以下のコードはhttp://www.scalaclass.com/book/export/html/1からマトリックスドット積を実行します。

中括弧の間の構文がわかりません。

  • 通常のメソッドの括弧ではなく、中括弧が使用されるのはなぜですか?
  • 匿名メソッドですか?
  • ._1と._2とは何ですか?

ありがとう。

type Row    = List[Double]
type Matrix = List[Row]

def dotProd(v1:Row, v2:Row) = 
    v1.zip(v2).map{ t:(Double, Double) => t._1 * t._2 }.reduceLeft(_ + _)
4

4 に答える 4

39
  • 通常のメソッドの括弧ではなく、中括弧が使用されるのはなぜですか?

パラメータが無名関数の場合、中括弧を使用することを好む人もいます。一つには、中括弧は無名関数とのパターンマッチングを可能にしますが、括弧はそうではありません。この特定の例では、中括弧は必要ありません。

中括弧が必要な例を次に示します(caseパターンマッチングのため)。

def dotProd(v1:Row, v2:Row) = 
    v1.zip(v2).map{ case (a, b) => a * b }.reduceLeft(_ + _)

上記の関数は、少し異なる方法で、質問の関数と同じことを実行することに注意してください。

  • t匿名メソッドですか?

いいえ、パラメータです。と同様v1に、はのv2パラメータであり、に渡される無名関数のパラメータです。dotProdtmap

  • ._1とは何._2ですか?

のメソッドt。パラメーターtはタプル(具体的にはTuple2[Double, Double]、と書くことができます)として定義されており、タプルを使用すると、、、、(Double, Double)などのメソッドを使用してタプルの各メンバーを抽出できます。_1_2_3

もちろん、とTuple2だけが_1あります。他の関数型言語の影響により_2、最初のパラメーターは_1ではなく、であることに注意してください。_0

とにかく、zipメソッドはRowList[Double])をに変換しList[(Double, Double)]ます。このメソッドmapは、リストの要素(タプル)を別の要素に変換する関数を取り(Double, Double)ます。

于 2012-05-03T17:42:28.690 に答える
22

この特定のケースでは、中括弧は単純な古い構文に勝る利点はありませんが、一般に中括弧を使用することの良い点は、パターンマッチング式を内部に記述できることですmap ...

だから私はこれを書き直すことができます

.map{ t:(Double, Double) => t._1 * t._2 }

これに

.map{ case(a: Double, b: Double) => a*b }

しかし、これはコンパイルされません:

.map( case(a: Double, b: Double) => a*b )

Leeが言ったように、._ 1、._2は、Nタプルの1番目、2番目、...N要素へのアクセスを提供します。

于 2012-05-03T12:44:49.200 に答える
5

この質問では、中かっこ{}とかっこ()の違いに対する非常に良い答えを見つけることができます。中かっことかっこの間のScalaの形式的な違いは何ですか、いつ使用する必要がありますか?

_1、_2については、scala言語での_2サインの意味を参照してください。

そして、はい、t:(Double, Double) => t._1 * t._2無名関数です(実際にはメソッドではありません)。Scalaのメソッドと関数の違い

于 2012-05-03T12:45:27.237 に答える
1

中括弧は、タイプが。の無名関数を示しますTuple2[Double,Double] => Double。引数にはローカル名が付けられているtのでt、2つのdoubleのタプルもあります。t._1最初のアイテムと2番目のアイテムを指しt._2ます。

したがってmap、2つのベクトルの成分の要素ごとの積のリストがreduceLeft生成され、これらの積を合計して内積が計算されます。

于 2012-05-03T12:03:29.863 に答える