Scala入门 - 如何从Map[String, Any]
创建一个Map[String,String]
Map[String,Any]
的值是字符串,但我不知道如何将"Any
"类型转换或以其他方式强制转换为"String
"类型。
Scala入门 - 如何从Map[String, Any]
创建一个Map[String,String]
Map[String,Any]
的值是字符串,但我不知道如何将"Any
"类型转换或以其他方式强制转换为"String
"类型。
正如您所提到的,您的映射中所有的值都是字符串,因此您可以简单地使用asInstanceOf
。如果您的假设不正确,则会收到如下所示的运行时异常:
$ scala
Welcome to Scala version 2.9.2 (OpenJDK 64-Bit Server VM, Java 1.7.0_55).
Type in expressions to have them evaluated.
Type :help for more information.
scala> val m:Map[String, Any] = Map("foo" -> 5, "bar" -> 7.6, "baz" -> "qux")
m: Map[String,Any] = Map(foo -> 5, bar -> 7.6, baz -> qux)
scala> val m2: Map[String, Any] = Map("foo" -> "5", "bar" -> "7.6", "baz" -> "qux")
m2: Map[String,Any] = Map(foo -> 5, bar -> 7.6, baz -> qux)
scala> m2.asInstanceOf[Map[String, String]]
res0: Map[String,String] = Map(foo -> 5, bar -> 7.6, baz -> qux)
当所有值实际上是String
类型时,这非常完美。
scala> res0("foo")
res5: String = 5
请注意您可能存在的错误假设:
scala> m.asInstanceOf[Map[String, String]]
res2: Map[String,String] = Map(foo -> 5, bar -> 7.6, baz -> qux)
scala> res2("foo")
java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String
at .<init>(<console>:10)
at .<clinit>(<console>)
at .<init>(<console>:11)
at .<clinit>(<console>)
at $print(<console>)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at scala.tools.nsc.interpreter.IMain$ReadEvalPrint.call(IMain.scala:704)
at scala.tools.nsc.interpreter.IMain$Request$$anonfun$14.apply(IMain.scala:920)
at scala.tools.nsc.interpreter.Line$$anonfun$1.apply$mcV$sp(Line.scala:43)
at scala.tools.nsc.io.package$$anon$2.run(package.scala:25)
at java.lang.Thread.run(Thread.java:744)
如果你一开始就有一个Map[String, Any]
,那么这很可能是出现了问题的迹象,但是如果没有代码提供,我也无法帮助你。通常情况下,当你开始看到Any
和其他超级通用类型被推断出来时,这意味着Scala的类型系统告诉你,你编写的代码并不是你想要的。
如果你真的想这样做,你可以这样做:
scala> val m = Map("foo" -> 5, "bar" -> 7.6, "baz" -> "qux")
m: scala.collection.immutable.Map[String,Any] = Map(foo -> 5, bar -> 7.6, baz -> qux)
scala> m.mapValues(_.toString)
res0: scala.collection.immutable.Map[String,String] = Map(foo -> 5, bar -> 7.6, baz -> qux)
Any
,但我坚持认为这可能表明存在逻辑错误,并且推断出一些不相关类型的最小上界。 - acjay正如其他人已经提到的那样,在第一次出现Any
的情况下,这表明某处出了问题。正确的解决方法是找出出了什么问题并修复它。
然而,如果你真的想将所有值都转换为String
(这是规避类型系统的做法,因此你不应该这样做),这里是如何实现:
val anyMap: Map[String, Any] = Map("foo" -> "bar", "baz" -> "qux")
val stringMap = anyMap.mapValues(_.asInstanceOf[String])
// => stringMap: Map[String, String] = Map(foo -> bar, baz -> qux)
编译器推断出的Map[String,Any]
的示例包括
val a = Map( "s" -> 1, "t" -> "w" )
a: scala.collection.immutable.Map[String,Any] = Map(s -> 1, t -> w)
Int和String的最不常见类型是Any
。
对映射中的每个值应用toString
。