5

私はscalaを初めて使用しますが、今日このakkaソースコードに出くわしたとき、私は戸惑いました。

def traverse[A, B](in: JIterable[A], fn: JFunc[A, Future[B]], 
      executor: ExecutionContext): Future[JIterable[B]] = {
    implicit val d = executor
    scala.collection.JavaConversions.iterableAsScalaIterable(in).foldLeft(
        Future(new JLinkedList[B]())) { (fr, a) ⇒
      val fb = fn(a)
      for (r ← fr; b ← fb) yield { r add b; r }
    }
  }

なぜコードは暗黙のパラメータを意図的に使用して書かれているのですか?なぜそれは次のように書くことができないのですか?

scala.collection.JavaConversions.iterableAsScalaIterable(in).foldLeft(
  Future(new JLinkedList[B](),executor))

新しい暗黙の変数をデカラーせずにd?これを行うことの利点はありますか?今のところ、暗黙的にコードのあいまいさが増すだけだと思います。

4

3 に答える 3

6

私はあなたに3つの理由を与えることができます。

1)ボイラープレートコードを非表示にします。

いくつかのリストを並べ替えましょう:

import math.Ordering

List(1, 2, 3).sorted(Ordering.Int) // Fine. I can tell compiler how to sort ints
List("a", "b", "c").sorted(Ordering.String) // .. and strings.
List(1 -> "a", 2 -> "b", 3 -> "c").sorted(Ordering.Tuple2(Ordering.Int, Ordering.String)) // Not so fine...

暗黙のパラメータを使用する場合:

List(1, 2, 3).sorted // Compiller knows how to sort ints
List(1 -> "a", 2 -> "b", 3 -> "c").sorted // ... and some other types

2)ジェネリックメソッドを使用してAPIを作成できます。

scala> (70 to 75).map{ _.toChar }
res0: scala.collection.immutable.IndexedSeq[Char] = Vector(F, G, H, I, J, K)

scala> (70 to 75).map{ _.toChar }(collection.breakOut): String // You can change default behaviour.
res1: String = FGHIJK

3)それはあなたが本当に重要なことに集中することを可能にします:

Future(new JLinkedList[B]())(executor) // meters: what to do - `new JLinkedList[B]()`. don't: how to do - `executor`

それほど悪くはありませんが、2つの先物が必要な場合はどうなりますか?

val f1 = Future(1)(executor)
val f2 = Future(2)(executor) // You have to specify the same executor every time.

Implicitは、すべてのアクションの「コンテキスト」を作成します。

implicit val d = executor // All `Future` in this scope will be created with this executor.
val f1 = Future(1)
val f2 = Future(2)

3.5)暗黙のパラメータにより、タイプレベルのプログラミングが可能になります。形のないを参照してください

「コードのあいまいさ」について:

暗黙的を使用する必要はありません。あるいは、すべてのパラメーターを明示的に指定することもできます。見た目が醜いこともありますが(sorted例を参照)、それは可能です。

パラメータとして使用されている暗黙の変数が見つからない場合は、コンパイラに問い合わせることができます。

>echo object Test { List( (1, "a") ).sorted } > test.scala
>scalac -Xprint:typer test.scala

あなたはmath.this.Ordering.Tuple2[Int, java.lang.String](math.this.Ordering.Int, math.this.Ordering.String)出力で見つけるでしょう。

于 2012-12-11T07:43:55.127 に答える
3

リンクしたAkkaのコードでは、エグゼキュータを明示的に渡すことができるのは事実です。ただし、このメソッド全体で複数のFutureパラメーターが使用されている場合は、暗黙的なパラメーターを宣言することは、それを何度も渡さないようにするために間違いなく理にかなっています。

したがって、リンクしたコードでは、暗黙のパラメーターは、コードスタイルに従うためだけに使用されていたと言えます。それから例外を作るのは醜いでしょう。

于 2012-12-11T07:55:57.360 に答える
1

あなたの質問に興味をそそられたので、ネットで少し検索しました。これが私がこのブログで見つけたものです:http://daily-scala.blogspot.in/2010/04/implicit-parameters.html

暗黙のパラメータとは何ですか?

暗黙的パラメーターは、暗黙的としてマークされたメソッドまたはコンストラクターへのパラメーターです。これは、パラメーター値が指定されていない場合、コンパイラーはスコープ内で定義された「暗黙の」値を検索することを意味します(解決規則に従って)。

なぜ暗黙のパラメータを使用するのですか?

暗黙的なパラメーターは、APIを単純化するのに非常に便利です。たとえば、コレクションは暗黙的なパラメーターを使用して、多くのコレクションメソッドにCanBuildFromオブジェクトを提供します。これは、通常、ユーザーがこれらのパラメーターを気にする必要がないためです。もう1つの例は、IOライブラリにエンコーディングを提供することです。これにより、エンコーディングは1回(おそらくパッケージオブジェクトで)定義され、すべてのメソッドは、メソッド呼び出しごとに定義しなくても同じエンコーディングを使用できます。

于 2012-12-11T07:19:57.570 に答える