2

マップを作成する場合:

val m = Map((4, 3))

そして、新しいキーと値のペアを追加してみてください:

val m_prime = m + (1, 5)

私は得る:

 error: type mismatch;
 found   : Int(1)
 required: (Int, ?)
       val m_prime = m + (1, 5)

私が行った場合:

val m_prime = m + ((1, 5))

または:

val m_prime = m + (1 -> 5)

その後、動作します。コンパイラが最初の例を受け入れないのはなぜですか?

私は2.10.2を使用しています

4

1 に答える 1

5

これは確かに非常に面倒です (私はこれに頻繁に出くわします)。まず第一に、この+メソッドは一般的なコレクションの特徴から来ており、引数を 1 つだけ (コレクションの要素の型) とります。Mapの要素タイプはペア(A, B)です。ただし、Scala はここでの括弧を、タプル コンストラクターではなく、メソッド呼び出しの括弧として解釈します。説明は次のセクションで示します。

これを解決するには、タプル構文を避けてkey -> value代わりに矢印の関連付けを使用するか、二重括弧を使用するか、またはupdatedに固有のメソッドを使用しMapます。updatedと同じことを+行いますが、キーと値を別々の引数として取ります。

val m_prime = m updated (1, 5)

なぜ Scala がここで失敗するのかはまだ不明です。なぜなら、一般的な中置構文は機能し、括弧を想定していないからです。メソッドのオーバーロードが原因で、この特定のケースが壊れているようです+。可変数のタプル引数を取る 2 番目のメソッドがあります。

デモンストレーション:

trait Foo {
  def +(tup: (Int, Int)): Foo
}

def test1(f: Foo) = f + (1, 2)  // yes, it works!

trait Baz extends Foo {
  def +(tups: (Int, Int)*): Foo // overloaded
}

def test2(b: Baz) = b + (1, 2)  // boom. we broke it.

私の解釈では、vararg バージョンが追加されたので、あいまいさが生じます。Is (a, b)aTuple2または 2 つの引数aandのリストです ( andが type でないb場合でも、おそらくコンパイラは暗黙的な変換を探し始めます)。あいまいさを解決する唯一の方法は、上記の 3 つのアプローチのいずれかを使用することです。abTuple2

于 2013-08-17T20:47:00.930 に答える