我如何获得typeArguments?

时间:2013-03-24 02:09:13

标签: scala types

我在某些2.9.2代码中使用man.typeArguments,但收到了Manifest s已被弃用的消息。我想出了如何使用typeOf[T]来访问<:<方法,但我不能在我的生活中找出typeArguments去过哪里。

对于上下文,我正在编写createParser[T: TypeTag]方法。如果TList[X],那么我会通过链接createParser[X]列表来创建其解析器。或者那就是我想要做的事。无论如何。

有人知道我应该从X(或TtypeOf[T]或任何其他可能的typeTag[T]相邻概念中获取T吗?

这是2.9.2中的代码:

  def getParser[T](implicit man: Manifest[T]): Parser[T] = {
    if (man <:< manifest[Stream[_]]) {
      val itemType = man.typeArguments(0)
      streamParser(itemType).asInstanceOf[Parser[T]]
    } else {
      parsers(man)().asInstanceOf[Parser[T]]
    }
  }

  def streamParser[T](implicit man: Manifest[T]): Parser[Stream[T]] = {
    val itemParser = getParser(man)
    (openParser("[") ~> repsep(itemParser, comma) <~ closeParser("]")) ^^ (_.toStream)
  }

这是我在2.10.1中尝试的内容,但没有太多运气:

  def getParser[T](implicit tag: TypeTag[T]): Parser[T] = {
    if (tag.tpe <:< typeOf[Stream[_]]) tag.tpe match {
      case TypeRef(_, _, List(itemType)) => streamParser(itemType).asInstanceOf[Parser[T]]
    } else {
      parsers(tag)().asInstanceOf[Parser[T]]
    }
  }

  def streamParser[T](implicit tag: TypeTag[T]): Parser[Stream[T]] = {
    val itemParser = getParser(tag)
    (openParser("[") ~> repsep(itemParser, comma) <~ closeParser("]")) ^^ (_.toStream)
  }

问题在于它说itemType是来自反射API的Type,但我无法弄清楚如何将其变成适合发送到{{TypeTag的{​​{1}} 1}}。

streamParser值实际上是从parsersTypeTag s的地图,将所有内容放入Parser方法并匹配可能会更清晰我要解析的东西的类型,但到目前为止,我对类型模式匹配的尝试似乎没有用。

我确信有一种简单的方法可以做到这一点 - 我想我只是陷入了一种新的实现和文档之间,而这些实现还没有赶上它。

1 个答案:

答案 0 :(得分:1)

在2.10(甚至2.11中更多)中,从类型和树中提取信息的方法是使用模式匹配,在本例中使用TypeRef

scala> typeOf[List[Int]] match { case TypeRef(_, _, args) => args }
res13: List[reflect.runtime.universe.Type] = List(Int)

scala> typeOf[Map[Int, String]] match { case TypeRef(_, _, args) => args }
res14: List[reflect.runtime.universe.Type] = List(Int, String)

scala> val TypeRef(_, _, args) = typeOf[List[Int]] // slightly shorter
args: List[reflect.runtime.universe.Type] = List(Int)