我尝试将一个元素添加到Scala HashMap
val c2 = new collection.mutable.HashMap[String,Int]()
c2 += ("hh",1)
但上面给出了编译错误。
[error] found : String("hh")
[error] required: (String, Int)
[error] c2 += ("hh", 1)
[error] ^
[error] /scalathing/Main.scala:5: type mismatch;
[error] found : Int(1)
[error] required: (String, Int)
[error] c2 += ("hh", 1)
[error] ^
[error] two errors found
[error] (compile:compileIncremental) Compilation failed
[error] Total time: 3 s, completed Sep 1, 2016 1:22:52 AM
我添加的对似乎是HashMap
所要求的正确类型。为什么我会收到编译错误?
答案 0 :(得分:4)
重载c2 += ("hh", 1)
运算符以使用可变参数。因此,当编译器看到->
时,它会将其解释为传入的两个参数,其中一个是“hh”而另一个是1.您可以使用c2 += ("hh" -> 1)
运算符来修复它,即c2 += (("hh, 1))
或将元组括在另一系列的parantheses中,即HashMap
。
根据评论中的要求,下面有一点点血腥的细节。
至于所有这些如何工作,在+=
等可变集合的情况下,.
只是一个用运算符语法调用的普通方法(即空格而不是Growable
)或Scala社区称之为"infix notation",因为Scala中的任何方法都可以。它由可变集合混合的Growable
特性提供。您可以在+=
的文档中看到单个参数c2.+=(("hh", 1))
方法和可变方法。换句话说,以下代码也会起作用。
+=
并非所有+=
都是相同的。 var
通常也会显示在.
中。尽管可以使用方法语法=
调用它,但它是由Scala编译器直接实现的神奇语法糖。特别是任何非字母数字名称后跟x $NAME= y
都会被贬低。 x = x.$NAME(y)
变为$NAME=
。在这种情况下,当且仅当$NAME
是可变参数时,var i = 0
i += 1
i.+=(1) // Also compiles
case class SuperInt(raw: Int) {
def &*&(x: SuperInt) = SuperInt(raw + x.raw)
}
var x = SuperInt(1)
x &*&= SuperInt(1) // This works
x.&*&=(SuperInt(1)) // As does this
x &*&= (SuperInt(1), SuperInt(1)) // Does not compile because &*& is not variadic
才是可变参数。
{{1}}