如果我创建地图:
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
答案 0 :(得分:5)
这确实很烦人(我经常遇到这种情况)。首先,+
方法来自一般的集合特征,只采用一个参数 - 集合的元素类型。 Map
的元素类型是(A, B)
对。但是,Scala将括号解释为方法调用括号,而不是元组构造函数。解释见下一节。
要解决此问题,您可以避免使用元组语法并使用箭头关联key -> value
,或使用双括号,或使用特定于updated
的方法Map
。 updated
与+
的作用相同,但将键和值作为单独的参数:
val m_prime = m updated (1, 5)
仍然不清楚为什么Scala在这里失败,因为一般的中缀语法应该工作而不是期望括号。由于方法重载,似乎打破了这个特殊情况:第二个+
方法采用了可变数量的元组参数。
<强>演示:强>
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版本的情况下,现在存在歧义:(a, b)
是Tuple2
还是两个参数列表a
和b
(即使a
和b
不是Tuple2
类型,也许编译器会开始寻找隐式转换)。解决歧义的唯一方法是使用上述三种方法中的任何一种。