问题
val m = scala.collection.mutable.Map[String, Int]()
// this doesn't work
m += ("foo", 2)
// this does work
m += (("foo", 2))
// this works too
val barpair = ("bar", 3)
m += barpair
So what's the deal with m += ("foo" , 2)
not working? Scala gives the type error:
error: type mismatch;
found : java.lang.String("foo")
required: (String, Int)
m += ("foo", 2)
^
Apparently Scala thinks that I am trying to call +=
with two arguments, instead of one tuple argument. Why? Isn't it unambiguous, since I am not using m.+=
?
回答1:
Unfortunately a b (c, d, e, ..)
desugars to a.b(c, d, e, ..)
. Hence the error.
回答2:
Isn't it unambiguous, since I am not using m.+= ?
No, it isn't, because parenthesis can always be used when there are multiple arguments. For example:
List(1, 2, 3) mkString ("<", ", ", ">")
So you might ask, what multiple parameters? Well, the Scala API doc is your friend (or mine, at least), so I present you with:
scala> val m = scala.collection.mutable.Map[String, Int]()
m: scala.collection.mutable.Map[String,Int] = Map()
scala> m += (("foo", 2), ("bar", 3))
res0: m.type = Map(bar -> 3, foo -> 2)
In other words, +=
takes a vararg.
回答3:
The preferred way to define map entries is to use the -> method. Like
m += ("foo" -> 2)
Which constructs a tuple. a -> b gets desugared to a.->(b). Every object in scala has a -> method.
来源:https://stackoverflow.com/questions/7744259/scala-map-ambiguity-between-tuple-and-function-argument-list