我如何获得类型参数? [英] How do I get typeArguments?
问题描述
我在某些 2.9.2 代码中使用了 man.typeArguments
,但收到一条消息,指出 Manifest
已被弃用.我想出了如何使用 typeOf[T]
来访问 <:<
方法,但我终生无法弄清楚 在哪里typeArguments
已经去了.
I was using man.typeArguments
in some 2.9.2 code, but got a message that Manifest
s are deprecated. I figured out how to use typeOf[T]
to access the <:<
method, but I can't for the life of me figure out where typeArguments
has gone to.
对于上下文,我正在编写一个 createParser[T: TypeTag]
方法.如果 T
是一个 List[X]
,那么我通过链接一个 createParser[X]
列表来创建它的解析器.或者,无论如何,这就是我想做的.
For context, I'm writing a createParser[T: TypeTag]
method. If T
is a List[X]
then I create its parser by chaining a list of createParser[X]
. Or that's what I'd like to do, anyway.
任何人都知道我应该如何从 T
(或 typeOf[T]
或 typeTag[T]
> 或任何其他可以想象的 T
-相邻概念?
Anybody know how I should get X
from T
(or typeOf[T]
or typeTag[T]
or any other conceivable T
-adjacent concept?
这是 2.9.2 中的代码:
Here's the code in 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 中尝试的,但运气不佳:
Here's what I'm trying in 2.10.1, but not having much luck with:
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
适用于发送到 streamParser
.
The problem is that it says itemType
is a Type
from the reflection API, but I can't figure out how to turn that into a TypeTag
suitable for sending to streamParser
.
那个 parsers
值实际上是一个从 TypeTag
s 到 Parser
s 的映射,把所有东西都放到getParser
方法并匹配我想要解析的事物的类型,但我对类型进行模式匹配的尝试到目前为止似乎还没有奏效.
That parsers
value is actually a map from TypeTag
s to Parser
s, and it would probably be cleaner to just put everything into the getParser
method and match on the type of the thing I want to parse, but my attempts at pattern matching on types haven't seemed to work so far.
我确信有一种简单的方法可以做到这一点——我想我只是被新的实现和尚未赶上它的文档夹住了.
I'm sure there's an easy way to do this--I think I'm just caught between a new implementation and documentation that hasn't caught up to it.
推荐答案
在 2.10 中(甚至在 2.11 中更多)从类型和树中提取信息的方法是使用模式匹配,在这种情况下使用 TypeRef
:
In 2.10 (and even more in 2.11) the way to extract information out of types and trees is to use pattern matching, in this case with 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)
这篇关于我如何获得类型参数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!