scala 3宏:从宏返回Map[String,Class[Any]]
我正试图针对scala 3.0.0-M3编写一个宏。我希望宏返回某个类型的选项[u]字段的内部类型。例如,假设:scala 3宏:从宏返回Map[String,Class[Any]],scala,macros,scala-macros,scala-3,Scala,Macros,Scala Macros,Scala 3,我正试图针对scala 3.0.0-M3编写一个宏。我希望宏返回某个类型的选项[u]字段的内部类型。例如,假设: class教授(val lastName:String,val id:Option[Int],val bossId:Option[Long]) 我想将id与Int相关联,将bossId与Long相关联 我有一些代码可以为基元类型执行此操作,并编译ok: 导入scala.quoted_ 导入scala.quoted.staging_ 导入scala.quoted.{Quotes,Ty
class教授(val lastName:String,val id:Option[Int],val bossId:Option[Long])
我想将id与Int相关联,将bossId与Long相关联
我有一些代码可以为基元类型执行此操作,并编译ok:
导入scala.quoted_
导入scala.quoted.staging_
导入scala.quoted.{Quotes,Type}
对象类型信息{
内联def字段信息[T(m.name->clazz))
}没有别的
}没有别的
}汤玛普先生
println(innerClassOfOptionFields)
Expr(innerClassOfOptionFields)
}
但如果我尝试使用它,就像这样:
class教授(val lastName:String,val id:Option[Int],val bossId:Option[Long])
对象主应用程序{
val fields=TypeInfo.fieldsInfo[教授]
}
编译器首先打印Map(id->int,bossId->long)
,因为宏代码中的println看起来不错,但随后失败:
[error] 16 | val fields = TypeInfo.fieldsInfo[Professor]
[error] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
[error] | Found: (classOf[Int] : Class[Int])
[error] | Required: Class[Any]
[error] | This location contains code that was inlined from Main.scala:34
我做错了什么?我不应该从宏返回贴图,或者可能不是这样
请注意,我的宏中的if/else逻辑实际上并不重要,问题可以归结为(在其他条件相同的情况下):
您可以在给定的基础上定义此缺失
导入scala.quoted_
用{
def应用(x:Class[?])(使用引号)={
导入quotes.reflect_
Ref(defn.Predef_classOf).appliedToType(TypeRepr.typeConstructorOf(x)).asExpr.asInstanceOf[Expr[Class[?]]
}
}
在Scala 3的下一个版本中,这应该不再是必需的。标准库的给定实例也适用于Class[?]
然后,您可以返回一个类型正确的映射[String,Class[?]]
inline def fieldsInfo:Map[String,Class[?]=${fieldsInfoMacro}
def fieldsInfoMacro(使用引号):Expr[Map[String,Class[?]]={
val结果:映射[字符串,类[?]]=Map(
“bossId”->classOf[scala.Long],
“id”->classOf[scala.Int]
)
Expr(结果)
}
一切正常:
scala>fieldsInfo
val res1:Map[String,Class[?]=Map(bossId->long,id->int)
我没有立即明白为什么它不起作用。可能是因为Expr.apply
如何将值提升到表达式中……但是有没有理由不使用Map[String,Class[\u]]
呢?@Jasper-M我第一次尝试使用Map[String,Class[\u]]
确实如此,但宏编译失败,出现以下错误没有引用类型的隐式参数。ToExpr[Map[String,Class[?]]]]
这就是我将所有内容都转换为Any的原因。我建议解决此问题:哇,这太棒了。谢谢!
val result: Map[String, Class[Any]] = Map(
"bossId" -> classOf[scala.Long].asInstanceOf[Class[Any]],
"id" -> classOf[scala.Int].asInstanceOf[Class[Any]]
)
Expr(result)