简体   繁体   English

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

[英]Get precise return type from a TypeTag and a method

Say I have 说我有

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

and want to obtain return type of bar when called on a Foo[Int] (ie Bar[Int] in this case) from the type tag of Foo[Int] and the name "bar" (we can assume there are no overloads or we can tell them apart). 并希望得到的返回类型bar上的调用时Foo[Int]Bar[Int]从类型标签在这种情况下) Foo[Int]和名称"bar" (我们可以假设没有过载或我们可以分辨他们)。 Can this be done done with scala-reflect? 这可以用scala-reflect完成吗?

Is this close to what you want (using asSeenFrom )? 这是否接近你想要的(使用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]

I've of course thrown type-safety out the window. 我当然把窗户式安全抛到了窗外。 Slightly better: 稍微好一些:

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])

In case someone runs into this in the future: with this variation 万一将来有人遇到这种情况:这种变化

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

val tt = typeTag[Bar[Int]]

I had to slightly change @mz's answer: 我不得不稍微改变@ mz的答案:

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

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM