0

man.typeArguments在一些 2.9.2 代码中使用,但收到一条Manifest已弃用的消息。我想出了如何使用typeOf[T]来访问该<:<方法,但我一生都无法弄清楚去哪里typeArguments了。

对于上下文,我正在编写一个createParser[T: TypeTag]方法。If Tis aList[X]那么我通过链接createParser[X]. 或者这就是我想做的,无论如何。

任何人都知道我应该如何XT(或typeOf[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)
  }

问题是它说itemTypeType来自反射 API,但我不知道如何将它变成TypeTag适合发送到streamParser.

parsers值实际上是从TypeTags 到Parsers 的映射,将所有内容放入getParser方法中并匹配我要解析的事物的类型可能会更干净,但我对类型进行模式匹配的尝试似乎并没有工作至今。

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

4

1 回答 1

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)
于 2013-03-24T11:10:12.830 回答