Scala 隐式宏分辨率
我试图得到一个由宏生成的隐式参数。请求StructTypeInfo隐式时,出现编译器错误,日志隐式显示:Scala 隐式宏分辨率,scala,macros,implicit-conversion,implicit,implicits,Scala,Macros,Implicit Conversion,Implicit,Implicits,我试图得到一个由宏生成的隐式参数。请求StructTypeInfo隐式时,出现编译器错误,日志隐式显示: [info] Test.scala:29: materializeCaseClassSchemaType is not a valid implicit value for org.apache.hadoop.hive.serde2.typeinfo.StructTypeInfo because: [info] hasMatchingSymbol reported error: We c
[info] Test.scala:29: materializeCaseClassSchemaType is not a valid implicit value for org.apache.hadoop.hive.serde2.typeinfo.StructTypeInfo because:
[info] hasMatchingSymbol reported error: We cannot enforce T is a case class, either it is not a case class or this macro call is possibly enclosed in a class.
我编译它的方法是将它包装在一个参数化类中:
trait SchemaWrapper[T] {
def schema: StructTypeInfo
}
以下是一些相关代码(如果我遗漏了什么,请告诉我):
有趣的是,如果我显式地将MaterializeCaseSeclassSchemaType[MyCaseClass]
传递给隐式位置中的函数,它就可以正常工作。为什么我需要包装纸,我能把它扔掉吗
// Implicits, one works, one doesn't
object MacroImplicits {
// Works:
implicit def materializeCaseClassSchemaTypeWrapper[T]: SchemaWrapper[T] = macro SchemaTypeImpl.caseClassSchemaTypeWrapper[T]
// Doesn't:
implicit def materializeCaseClassSchemaType[T]: StructTypeInfo = macro SchemaTypeImpl.caseClassSchemaType[T]
}
// Implementation (most of it probably not relevant)
// Another version returns StructTypeInfo directly without the wrapper
object SchemaTypeImpl {
def caseClassSchemaTypeWrapper[T](c: Context)(implicit T: c.WeakTypeTag[T]): c.Expr[SchemaWrapper[T]] = {
import c.universe._
if (!IsCaseClassImpl.isCaseClassType(c)(T.tpe))
c.abort(c.enclosingPosition, s"""We cannot enforce ${T.tpe} is a case class, either it is not a case class or this macro call is possibly enclosed in a class.""")
...
}
}