【发布时间】:2017-09-15 18:08:59
【问题描述】:
我有Map[String, Any],例如来自 JSON 反序列化器:
def map: Map[String, Any] = Map("hello" -> Map("world" -> "value"))
我想得到嵌套键"hello"."world"的Option:
val value = map.get("hello").flatMap {
case m: Map[String, String] => m.get("value")
case _ => None
}
assert(value == Some("value"))
但是这个解决方案不是类型安全的——它会发出警告“因为它被擦除而被消除,所以它是未经检查的”,并且会在错误的值类型上失败。
如何以安全的方式做到这一点?如果嵌套对象是包含键 "world" 或 None 的有效/兼容类型的映射,则返回值?
编辑:这与Manifest[] 或TypeTag[] 无关。我知道在运行时无法访问确切的 Map 类型,但想要比以某种方式强制转换键更好的解决方案(顺便说一句,这安全吗?)并为值执行 isinstanceof。
【问题讨论】:
-
您的代码不起作用。在
flatMap中,您已经拥有Any而不是Option[Any]。但除此之外,这是一个有效的问题。我认为答案是你不能这样做。 -
@DanielDarabos
m.get返回Option[String]所以代码是有效的 -
@Suma 我不认为这是重复的。你不能用
TypeTags解决问题 -
m.get返回Option[Any]。但这不是重点。flatMap让您在Option[Any]的内部 上进行操作。所以你需要case m: Map[String, String]而不需要case None。试一试,你就会看到。 -
@DanielDarabos 有一个解决方案,但它过于丑陋且不实用。你可以匹配
Map[_,_],遍历键并检查它们的类型。不幸的是,我没有任何其他想法