Scala:Accessing/casting 来自 Map[String, Any] 的条目或更好的选择

Scala: Accessing/casting entries from Map[String, Any] or better alternative

通过模式匹配,我从 AST 中提取属性并将它们保存在 Map[String, Any] 中,因为它们可以是字符串、整数、列表等。现在我想在一个案例中使用这些属性 class。为了获取元素,我写了这个方法:

def getAttr(attr: Map[String, Any], key : String):Any = {
   val optElem = attr.get(key) match {
     case Some(elem) => elem
     case _ => throw new Exception("Required Attribute " + key + " not found")
  }
}

因为我总是知道每个属性值是什么类型,所以我想使用这样的值:

case class Object1(id: String, name: String)

Object1("o1", getAttr(attrMap, "name").asInstanceOf[String])

但是我收到错误 "scala.runtime.BoxedUnit cannot be cast to java.lang.String"

我做错了什么?或者有没有更好的方法来收集和使用我的属性?

您的 getAttr 实现具有 Unit 类型,因为您 return 将值赋值给 optElem

修复:

def getAttr(attr: Map[String, Any], key : String):Any = {
  attr.get(key) match {
    case Some(elem) => elem
    case _ => throw new Exception("Required Attribute " + key + " not  found")
  }
}

作为@Nyavro 绝对正确答案的补充:为了避免每次使用 getAttr 时都调用 asInstanceOf,您可以向其添加类型参数:

def getAttr[R](attr: Map[String, Any], key: String): R = {
   val optElem = attr.get(key) match {
     case Some(elem) => elem
     case _ => throw new Exception("Required Attribute " + key + " not found")
   }
   optElem.asInstanceOf[R]
}

然后

Object1("o1", getAttr(attrMap, "name"))