使用Scala的模式匹配来匹配参数化类型

时间:2014-12-03 01:16:10

标签: scala

object Helper {

  case class IsMap(x: Map[String,Any])
  case class IsT[T](t: T)

  implicit class MapFunctions(val map: Map[String,Any]) {

    def path[T](path : String*) : Option[T] = {

      if(path.size == 1)
        None

      map.get(path.head).get match {
        case IsMap(item) => item.path(path.tail:_*)
        case IsT(item) => Option(item)
        case _ => throw new Exception("Unexpected type encountered in path")
      }
    }
  }
}

我还是Scala的新手。我想避免模式匹配的IsT(item)部分中的Option(item.asInstanceOf [T])。我正在使用案例类来模式匹配参数化类型以停止类型擦除。我想要做的是只有当项目类型为T时才能使IsT(项目)匹配。运行此代码似乎不匹配。我做错了什么?

更新:直到今晚,我认为Scala已经神奇地解决了Java所具有的类型擦除的一些更糟糕的问题。我知道有时候还会出现类型擦除但我没有意识到它几乎一样。我玩了一下TypeTag。我对Scala中的类型干扰感到兴奋,并且能够让它推断出我试图返回的类型,但是有了my myType = path(“blah”,“blah”)。搞砸了这个,因为推断的类型是Nothing这会导致投射错误。我最终解决了这个问题,就像我在java中解决它一样 - 使用path()方法获取Class [T]并将其用作参数化返回类型。这很不幸......不知怎的,我认为Scala能够做得更多......

无论如何 - 我的新方法看起来像这样:

object Helper {

  implicit class MapFunctions[K,V](val map: Map[K,V]) {

    def path[T<:V](clazz: Class[T], pathParts: K*): Option[T] = {

      if (pathParts.size == 0)
        None
      else {
        map.get(pathParts.head).get match {
          case im: Map[K, V] if pathParts.size > 1 => im.path(clazz, pathParts.tail: _*)
          case i => Option(i.asInstanceOf[T])
        }
      }
    }
  }
}

哦......这隐含的目的是什么?我的团队花了大约一周时间试图在Scala中找到一个好的json库。我们之前使用过json4s,但对它的容器对象存储了Tuple2的List而不是map的事实并不满意,我们正在进行访问,所以这对我们不起作用。我们已经恢复使用Jackson并将json反序列化为Map [String,Any]。我发现自己正在做的事情,我想像树一样将地图级联到嵌套对象中,这种“路径”方法似乎是合理的,能够做到这一点。

0 个答案:

没有答案