我很困惑为什么Scala不允许它能够推断的东西。如果我想在Map中存储任意类型,我想这应该是可能的,但是在似乎有足够信息来执行操作时被阻止。
scala> var m: Map[Any, Any] = Map()
m: Map[Any,Any] = Map()
scala> m = ("one" -> 1, 2 -> "two", 3 -> 3)
<console>:8: error: type mismatch;
found : ((String, Int), (Int, String), (Int, Int))
required: Map[Any,Any]
m = ("one" -> 1, 2 -> "two", 3 -> 3)
^
scala> m += ("one" -> 1)
scala> m += (2 -> "two")
scala> m += (3 -> 3)
scala> m
res25: Map[Any,Any] = Map(one -> 1, 2 -> two, 3 -> 3)
scala> m("one").getClass
res26: Class[_] = class java.lang.Integer
scala> m(3).getClass
res27: Class[_] = class java.lang.Integer
scala> val result = m("one")+m(3)
<console>:8: error: type mismatch;
found : Any
required: String
val result = m("one")+m(3)
^
scala> val result: Int = m("one")+m(3)
<console>:8: error: type mismatch;
found : Any
required: String
val result: Int = m("one")+m(3)
^
scala> val mr1 = m("one")
mr1: Any = 1
scala> val mr1 = m("one") => Int
<console>:1: error: not a legal formal parameter.
Note: Tuples cannot be directly destructured in method or function parameters.
Either create a single parameter accepting the Tuple1,
or consider a pattern matching anonymous function: `{ case (param1, param1) => ... }
val mr1 = m("one") => Int
^
最终我知道Key(字符串)的类型,并且由于值的真实类型是已知的,我应该至少能够投射它们,对吧?我也意识到代码必须是类型安全的。
我显然正在接受审判,而且大多数是错误,有人可以提供指导。
答案 0 :(得分:3)
这是错误的:
m = ("one" -> 1, 2 -> "two", 3 -> 3)
您正尝试将Tuple3
分配给m
,您声明为Map[Any,Any]
。你的意思是:
m = Map("one" -> 1, 2 -> "two", 3 -> 3)
但是,值得注意的是,在代码中使用Any
类型的东西几乎肯定是个坏主意。类型安全性很好,是使用Scala的主要好处之一。你应该利用它。
答案 1 :(得分:3)
在
m = ("one" -> 1, 2 -> "two", 3 -> 3)
您尝试分配到m
,因此右侧必须与Map[Any, Any]
兼容。但是,("one" -> 1, 2 -> "two", 3 -> 3)
是一个不兼容的元组,因此是错误。
在
m += ("one" -> 1)
您使用+
参数调用Map[Any, Any]
Tuple2[Any, Any]
方法。虽然("one" -> 1)
的类型为(String, Int)
,但它与(Any, Any)
兼容,因此可以单独添加。{/ p>
请注意,您也可以这样做:
m += ("one" -> 1, 2 -> "two", 3 -> 3)
当您在地图中查找元素时,返回值的类型为Any
,因此m("one")
和m(3)
的类型都是Any
。由于Any
没有+
运算符,m("one")+m(3)
将无法编译。如果您知道这两个值都是Int
s,那么您可以投射它们:
m("one").asInstanceOf[Int] +m(3).asInstanceOf[Int]