これは確かに非常に面倒です (私はこれに頻繁に出くわします)。まず第一に、この+メソッドは一般的なコレクションの特徴から来ており、引数を 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