如何使用Scala Map [A​​ny,Any]

时间:2014-05-22 18:35:22

标签: scala polymorphism

我很困惑为什么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(字符串)的类型,并且由于值的真实类型是已知的,我应该至少能够投射它们,对吧?我也意识到代码必须是类型安全的。

我显然正在接受审判,而且大多数是错误,有人可以提供指导。

2 个答案:

答案 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]