len*_*nkt 7 macros scala scala-macros
我理解Scala中宏的基本概念,但目前无法做到这一点(简单?)的工作:
defs/vals,以从给定类型转换为另一个类型.我会期望得到的是一个List的Method物体或类似的东西.我已经玩过,enclosingImplicits但总是得到一个空列表,并不知道下一步该在哪里.
我需要做什么才能获得我想要的列表?
在上下文中从 typeA到只能有一个隐式(或者你会得到不明确的隐式),所以如果你想找到它:B
import reflect.macros.Context, scala.language.experimental.macros
def fImpl(c: Context): c.Expr[Unit] = {
import c.mirror._
println(c.inferImplicitValue(typeOf[Int]))
c.universe.reify( () )
}
def f = macro fImpl
scala> f
<empty>
scala> implicit val a = 5
a: Int = 5
scala> f
$line24.$read.$iw.$iw.$iw.$iw.a
scala> implicit val b = 5
b: Int = 5
scala> f //result will be empty, but error printed to the log
error: ambiguous implicit values:
both value a of type => Int
and value b of type => Int
match expected type Int
<empty>
Run Code Online (Sandbox Code Playgroud)
查找隐式方法:
def fImpl(c: Context): c.Expr[Unit] = {
import c.mirror._
println(c.inferImplicitValue(typeOf[String => Int]))
c.universe.reify( () )
}
def f = macro fImpl
scala> f
<empty>
scala> implicit def aaa(a: String) = 5
warning: there was one feature warning; re-run with -feature for details
aaa: (a: String)Int
scala> "A" : Int
res10: Int = 5
scala> f
{
((a: String) => $line47.$read.$iw.$iw.$iw.$iw.$iw.$iw.aaa(a))
}
Run Code Online (Sandbox Code Playgroud)
如果silent参数为false(true默认情况下),TypecheckException则在出现推理错误时将抛出异常。所以你可以分析它来找到不明确的隐式列表。
PS 如果类型B未知 - 没有(记录的)方法可以使用宏查找所有隐式:openImplicits/enclosingImplicits只是寻找在宏扩展上下文中具体化的隐式 - 不适用于上下文中存在的所有隐式。编译器插件可能会有所帮助,但并不那么容易。
如果您真的决定尝试“编译器插件”方式 - 查找隐式的逻辑就在这里实现。在这里您可以找到编译器Context(与宏不同)及其implicitss字段,其中包含上下文中的所有隐式内容(但获取适当的上下文并不是那么简单)。
我不应该告诉你,但有一个棘手且不安全的黑客可以从宏提升Context到编译器级别并执行你想要的操作:
scala> def fImpl(c: Context): c.Expr[Unit] = {
| val cc = c.asInstanceOf[reflect.macros.contexts.Context]
| println(cc.callsiteTyper.context.implicitss.flatten)
| c.universe.reify( () )
| }
fImpl: (c: reflect.macros.Context)c.Expr[Unit]
scala> def f = macro fImpl
scala> f //I've defined aaaaaaaa etc. implicits while playing with that
List(aaaaaaaa: ?, lllllllllllllllllllllzzzz: ?, lllllllllllllllllllll: ?, lllllllllllllllllllll: ?, aaa: ?, aaa: ?, aaa: ?, aaa: ?, aaa: ?, aaa: ?, b: ?, a: ?, macros: ?, RuntimeClassTag:
Run Code Online (Sandbox Code Playgroud)
无论如何,您必须分析一个列表ImplicitInfo才能获得您正在寻找的隐式,这可能并不简单,正如您从Analizer的来源中看到的那样,但至少可以获得近似结果,这可能适合您的需求。但同样,最好非常非常小心地这样做,因为您使用的结构是可变的并且方法不是纯粹的。而且,正如@Eugene Burmako 注意到的那样,这个解决方案不会为您提供伴随对象的隐含信息。
| 归档时间: |
|
| 查看次数: |
667 次 |
| 最近记录: |