【问题标题】:Terse way to downcast container contents向下转换容器内容的简洁方法
【发布时间】:2014-01-21 19:27:17
【问题描述】:

我经常发现自己在做类似的事情:

val json:Map[String,Any] = getJSON(...)

val v = json.get("username")
val uname = if ( v!=null ) v.asInstanceOf[toString] ) else null

而我更喜欢写的是:

val uname = json.get[String]("username")

但是 get 不接受类型参数——所以我的代码过于冗长如下:

val uname = json.get("username").asInstanceOf[String]

在这种情况下如何简化对容器的访问? (对于 JSON 样式的对象,我经常这样做)

【问题讨论】:

  • (null: Object).asInstanceOf[String] 工作得很好。还要注意Map 上的get 返回Option[T],在这种情况下Option[Any] 永远不会是null。可能是Some(null),但不是null
  • 不是一个答案,但在 Scala 中处理 JSON 有很多更好的方法,不涉及 Map[String, Any]——例如我的答案 here
  • @senia -- 非常正确。已修改问题。

标签: scala scala-collections downcast


【解决方案1】:

使用implicits可以轻松实现:

implicit class MapWGet(m: Map[String, Any]) {
  // something like this
  def gett[T](k: String): T = m(k).asInstanceOf[T]
}

但请注意,null 上的 asInstance 值类型(IntDouble 等)会产生零值(但您可以轻松修改方法以满足您的要求)。

scala> val json: Map[String, Any] = Map("s" -> "String", "i" -> 1, "n" -> null, "d" -> 0.10D)
json: Map[String,Any] = Map(s -> String, i -> 1, n -> null, d -> 0.1)

scala> json.gett[String]("s")
res0: String = String

scala> json.gett[String]("n")
res1: String = null

scala> json.gett[Int]("n")
res2: Int = 0

scala> json.gett[Double]("d")
res3: Double = 0.1

scala> json.gett[Int]("i")
res4: Int = 1

【讨论】:

  • 效率如何?是否为每次调用 gett 创建一个新对象?
  • 实际上这是在编译时完成的,基本上被翻译成gett(m, k)。我记得没有创建新实例。您可能想阅读stackoverflow.com/questions/6381940/…
猜你喜欢
  • 2015-04-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-05-12
  • 2011-01-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多