2017-02-08 22 views
1
Array("hi","there").map(println) 
Array("hi","there").map(s => println(s)) 
Array("hi","there").map(println(_)) 

上記のステートメントのそれぞれは、mapの最初の2つの引数で同じ出力が得られますが、最後のものは関数の呼び出しです。スカラ:mapへの引数は、関数OR呼び出しです。

どのようにマップ両方を扱うことができますか?

署名TraversableLikeクラスのマップ

は、このようなものです:

def map[B, That](f: scala.Function1[A, B])(implicit bf: scala.collection.generic.CanBuildFrom[Repr, B, That]) : That = { /* compiled code */ } 

答えて

2

どのようにマップの両方を扱うことができるのですか?

コンパイラはprintlneta-expansionを実行することにより、mapためmethod valueを作成したので、両方を扱うことが可能です。 Scalaでは、メソッドと関数の間に区別があります。メソッドと関数の間には、値が格納されていないため、コンパイラは余裕を持って動作させる必要があります。

コンパイライータ展開が実際に放出した後:

Array("hi","there").map(s => println(s)) 

あなたの第二の例をマッチング。実際のコードは、より冗長であるが、同じことを意味する:

scala.this.Predef.refArrayOps[String](
    scala.Array.apply[String]("hi", "there")(
    (ClassTag.apply[String](classOf[java.lang.String]): scala.reflect.ClassTag[String]))) 
    .map[Unit, Any]({((x: Any) => scala.this.Predef.println(x)) 
    })(scala.this.Array.canBuildFrom[Unit]((ClassTag.Unit: scala.reflect.ClassTag[Unit]))); 

@sloucコメントで述べたように、プレースホルダの構文を使用して、第三の例が2番目の一例に相当させるれ、s => println(s)にdesugeredれます。完了していないので、重要な注意点として

println以来の戻り UnitArray.foreachはこちらより適しているであろう:

Array("hi","there").foreach(println) 
+2

私はちょうど第一と第三ケースの両方が第二1に変換されていることを追加し、しかしでしまいます異なるメカニズム。 (println(_) 'と' s => println(s))は文字通り同じものですが、前者は後者の短い形式です)。 'def foo = println'の型は'(String)=> Unit'ではなく 'Unit'であるため、コンパイラは最初の例をマップの定義に適合させることができません。一方、 'def foo = println(_)'は '(String)=> Unit'型であるため、2回目と3回目の作業はそのままです。 – slouc

+1

@slouc答えに追加! –

関連する問題