Подтвердить что ты не робот

Поиск параметров типа через отражение в Scala 2.10?

Используя теги типа, я могу видеть параметры некоторого типа:

scala> import scala.reflect.runtime.universe._
import scala.reflect.runtime.universe._

scala> typeOf[List[Int]]
res0: reflect.runtime.universe.Type = List[Int]

Но я просто не могу понять, как программно получить этот "Int" оттуда в общем виде.

(Я бродил по REPL в течение часа, пытаясь перестановки в Type, чтобы увидеть, что я могу получить от него... Я получаю много вещей, которые указывают, что это "Список", но хороший удачи в поиске этого "Int" ! И я действительно не хочу прибегать к анализу вывода toString()...)

Даниэль Собрал имеет отличный (как обычно) быстрый обзор здесь, в котором он мучительно близок к тому, что я ищу, но (по-видимому), только если вы знаете, для этого конкретного класса, какой-то конкретный метод, тип которого можно опросить:

scala> res0.member(newTermName("head"))
res1: reflect.runtime.universe.Symbol = method head

scala> res1.typeSignatureIn(res0)
res2: reflect.runtime.universe.Type = => Int

Но я надеюсь на что-то более общее, что не связано с укоренением в списке объявленных методов и надеется, что один из них будет захватывать (и тем самым разглашать) тег текущего типа информации где-то.

Если Scala может так легко напечатать "Список [Int]", почему же так трудно обнаружить, что часть "Int" этого - не прибегая к сопоставлению строк? Или я просто пропустил что-то действительно, действительно очевидное?

scala> res0.typeSymbol.asInstanceOf[ClassSymbol].typeParams
res12: List[reflect.runtime.universe.Symbol] = List(type A)

scala> res12.head.typeSignatureIn(res0)
res13: reflect.runtime.universe.Type = 

Grr...

4b9b3361

Ответ 1

К сожалению, я не думаю, что есть метод, который даст вам параметры, но вы можете получить их так:

Welcome to Scala version 2.10.0-20121007-145615-65a321c63e (Java HotSpot(TM) 64-Bit Server VM, Java 1.6.0_35).
Type in expressions to have them evaluated.
Type :help for more information.

scala> import scala.reflect.runtime.universe._
import scala.reflect.runtime.universe._

scala> typeOf[List[Int]]
res0: reflect.runtime.universe.Type = scala.List[Int]

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

scala> res1.head
res2: reflect.runtime.universe.Type = Int

Edit Здесь немного лучший способ добиться того же (после обсуждения scala -internals):

scala> res0.asInstanceOf[TypeRefApi].args
res1: List[reflect.runtime.universe.Type] = List(Int)