从TypeTag和方法获取精确的返回类型

时间:2015-03-25 13:21:54

标签: scala reflection scala-reflect

说我有

trait Foo[T] { def bar: Bar[T] }

并希望在bar的类型标记Foo[Int]Bar[Int]上调用Foo[Int]时获得"bar"的返回类型1}}(我们可以假设没有重载,或者我们可以区分它们)。这可以用scala-reflect完成吗?

2 个答案:

答案 0 :(得分:4)

这是否接近你想要的(使用asSeenFrom)?

val tt = typeTag[Foo[Int]]

scala> tt.tpe
    .members
    .find(_.name.toString == "bar").get
    .asMethod
    .returnType
    .asSeenFrom(tt.tpe, tt.tpe.typeSymbol)

res68: reflect.runtime.universe.Type = Bar[Int]

我当然把窗户式安全抛到了窗外。稍微好一些:

scala> tt.tpe
     .members
     .find(_.name.toString == "bar")
     .filter(_.isMethod)
     .map(_.asMethod.returnType.asSeenFrom(tt.tpe, tt.tpe.typeSymbol))

res74: Option[reflect.runtime.universe.Type] = Some(Bar[Int])

答案 1 :(得分:2)

如果将来有人遇到此问题:使用此变体

trait Foo[T] { def bar: Option[T] }
trait Bar[T] extends Foo[T]

val tt = typeTag[Bar[Int]]

我不得不稍微改变@ m-z的答案:

val m = tt.tpe
  .member(newTermName("bar"))
  .asMethod

m.returnType
  .asSeenFrom(tt.tpe, m.owner)