gpt4 book ai didi

scala - 在宏上下文中查找隐式方法定义

转载 作者:行者123 更新时间:2023-12-04 12:30:51 26 4
gpt4 key购买 nike

我了解 Scala 中宏的基本概念,但目前无法执行此(简单?)工作:

  • 查找所有隐式 def s/val s 当前对编译器可见以从给定类型转换为另一种类型。

  • 我希望得到的是 ListMethod对象或类似的东西。我已经玩过 enclosingImplicits但总是得到一个空列表并且不知道下一步该往哪里看。

    我需要做什么才能得到我正在寻找的 list ?

    最佳答案

    类型 A 中只能有一个隐式至 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>

    查找隐式方法:
    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))
    }

    silent参数为 false ( true 默认), TypecheckException将在推理错误的情况下抛出。因此,您可以对其进行分析以找到含糊不清的隐含列表。

    附言如果输入 B未知 - 没有(记录在案的)使用宏查找所有隐式的方法: openImplicits/ enclosingImplicits只是寻找在宏观扩展的上下文中具体化的隐式 - 不是所有的,存在于上下文中。 Compiler-plugin 可能会有所帮助,但它并不那么容易。

    如果您真的决定尝试“编译器插件”方式 - 实现了查找隐式的逻辑 here . Here你可以找到编译器的 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:

    无论如何,你必须分析一个列表 ImplicitInfo 获得您正在寻找的隐式,这可能不是微不足道的,正如您从 Analizer 中看到的那样的来源,但至少可以获得近似结果,这可能适合您的需求。但同样,最好这样做 非常非常非常小心 ,因为您使用的结构是可变的,并且方法不是纯的。而且,正如@Eugene Burmako 所注意到的,这个解决方案不会给你来自伴随对象的隐含信息。

    关于scala - 在宏上下文中查找隐式方法定义,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29834187/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com