我正在努力解决问题而我无法实现如何解决问题。我希望更有经验的Scala程序员可以为我提供帮助!
我有以下宏:
object Model {
trait Model[T <: Product] {
def showAttrs(): Unit
}
def getModel[T <: Product]: Model[T] = macro getModelImpl
}
宏的目的是返回一个显示T&#39属性的Model实例(如果T是一个案例类)!
我希望能够做到以下几点:
def f[T <: Product](implicit m: Model[T]): Unit = {
m.showAttrs()
}
case class Number(n: Int)
f[Number]()
当我们执行以下操作时,原理与scala反射相同:
case class Number(n: Int)
def getInfo[T](implicit tag: TypeTag[T]): Unit = println(tag)
请参阅?我们得到了一个类型:)的实例(太棒了!)。
怎么做这样的事情? scala反射包是否在幕后提供了一些具体内容?如果是这样,我怎样才能达到同样的效果呢?
答案 0 :(得分:3)
你的MyTypeTag[T]
应该完成什么?
如果你的特征在T
上是不变的,并且根本没有任何类型相关的逻辑,那么最简单的解决方案就是定义方法
implicit def arbMyTypeTag[T] = new MyTypeTag { ... }
更复杂的变体取决于其他已解决的含义
implicit def optionMonoid[T: Semigroup] = new Monoid[Option[T]] { ... }
更复杂的变体取决于相同的类型
implicit def tupleMonoid[A,B](implicit ma: Monoid[A], mb: Monoid[B]) = new Monoid[(A,B)]{...}
编译器能够解决此类递归暗示。
最核心的方法是通过implicit macro使用与TypeTag
分辨率最接近的类型和表达式的完整编译时信息,这可能会导致very complex bugs