You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Scala 3 宏如何获取外层作用域变量的初始化体?

问题原因

外层作用域变量无法提取初始化代码的核心原因是Scala 3宏默认不会预加载非局部作用域符号的完整定义树:只有和宏调用处在同一局部展开上下文的符号,symbol.tree才会自带完整的ValDef右值信息,外层作用域、跨编译单元的符号默认只加载签名信息,右值部分为None。

解决方案

调整宏实现,先调用符号的complete()方法强制加载完整定义树,再访问树结构即可:

def extractBodyImpl[T: Type](expr: Expr[T])(using Quotes) =
    import quotes.reflect._
    expr.asTerm.underlyingArgument match
        case ident @ Ident(_) =>
            val sym = ident.symbol
            // 强制加载符号的完整源码定义
            sym.complete()
            sym.tree match
                case ValDef(_,_,rhs) => println(rhs)
                case DefDef(_,_,_,rhs) => println(rhs)
    '{ () }

inline def extractBody[T](inline expr: T) = ${ extractBodyImpl('expr) }

额外注意事项

  • 如果变量定义在和宏调用不同的编译单元,需要将变量声明为inline val,否则宏无法读取跨编译单元非内联变量的源码级初始化表达式。
  • 已经编译成字节码的外部依赖库中的变量,无法通过该方法提取初始化代码,不存在对应的源码树信息。

内容的提问来源于stack exchange,提问作者YuliaSp

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 09:57:01