我正在使用宏来实现给定typename中的字符串,在TypeInfo
类型类中实现。我有一个EntityName
类型类,它使用TypeInfo
提供的名称并对其进行格式化。
最后,我想在EntityName
个对象中使用Usage
来派生A
类的名称。
因此,在一个单独的编译单元中,我有以下简单的宏包:
游乐场/ TypeInfoMacros.scala
package playground
import macrocompat.bundle
import scala.reflect.macros.whitebox
@bundle
private class TypeInfoMacros(val c: whitebox.Context) {
import c.universe._
def matTypeInfoImpl[A: c.WeakTypeTag]: Tree = {
val A = c.weakTypeOf[A]
val name = A.typeSymbol.name.decodedName.toString.trim
q"new TypeInfo[$A] { def name = $name }"
}
}
在我的主编译单元中,我有TypeInfo
类型类与隐式宏构造器:
游乐场/ util的/ TypeInfo.scala
package playground.util
import scala.language.experimental.macros
trait TypeInfo[A] { def name: String }
object TypeInfo extends TypeInfoInstances {
def apply[A](implicit ti: TypeInfo[A]): TypeInfo[A] = ti
}
trait TypeInfoInstances {
implicit def materializeTypeInfo[A]: TypeInfo[A] = macro playground.TypeInfoMacros.matTypeInfoImpl[A]
}
EntityName
类型类看起来像这样:
游乐场/ EntityName.scala
package playground
import playground.util.TypeInfo
trait EntityName[T] {
val value: String
}
object EntityName {
def apply[T](implicit entityName: EntityName[T]): String = entityName.value
implicit def entity[T: TypeInfo]: EntityName[T] = new EntityName[T] {
override val value: String = implicitly[TypeInfo[T]].name // not too complicated formatting :)
}
}
我创建了一个implicits对象,用于混合项目中的所有实例:
游乐场/ implicits.scala 包运动场
import playground.util.TypeInfoInstances
object implicits extends TypeInfoInstances
最后用法:
游乐场/ Usages.scala
package playground
class X
object UsageA {
import playground.util.TypeInfo
EntityName[X] // works!
}
object UsageB {
import playground.implicits
EntityName[X] // could not find implicit value for parameter entityName: playground.EntityName[playground.X]
}
object UsageC {
implicit val instance = new playground.util.TypeInfoInstances{}
EntityName[X] // could not find implicit value for parameter entityName: playground.EntityName[playground.X]
}
我的诊断:
对我而言,如果未明确导入TypeInfo
特征,则不会实现实现。我觉得很奇怪,因为如果我将materializeTypeInfo
更改为正常函数,请说
implicit def materializeTypeInfo[A]: TypeInfo[A] = new TypeInfo[A] { def name = "something "}
然后所有3个都在工作。
我正在使用Scala 2.11.12
TypeInfo
?