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

Scala 3宏:如何在引用代码块中调用Symbol获取的方法?

Scala 3宏中调用伴生对象方法Symbol的正确实现

在Scala 3宏里,直接将方法的Symbol传入准引号('{...})会报错,因为准引号仅接受Expr类型。要实现调用,需先把Symbol转换为对应的Expr,具体步骤如下:

  1. 在quotes反射上下文内构建方法引用
    借助Scala 3反射API的Ref节点,将方法Symbol包装为反射节点,再通过asExpr转换为Expr。如果是无参方法,可使用Expr.betaReduce处理方法引用的eta展开问题。

  2. 在准引号中调用转换后的Expr
    将转换得到的Expr传入准引号,即可像普通代码一样调用目标方法。

示例代码:

import scala.quoted.*

def exampleMacro[T: Type](using Quotes): Expr[List[String]] = {
  import quotes.reflect.*

  // 获取T的伴生类及目标方法Symbol(以"list"方法为例)
  val companionSym = TypeRepr.of[T].typeSymbol.companionClass
  val listMethodSym = companionSym.declarations
    .find(_.name == "list")
    .getOrElse(throw new IllegalArgumentException("未找到list方法"))

  // 将方法Symbol转换为Expr
  val listMethodExpr = Ref(listMethodSym).asExpr
  // 处理无参方法的eta展开
  val reducedListMethodExpr = Expr.betaReduce(listMethodExpr)

  // 在准引号中调用方法
  '{
    $reducedListMethodExpr.map(_.toString)
  }
}

关键说明

Scala 3宏系统对反射节点和Expr的隔离更严格,不像Scala 2的准引号可直接接受Symbol。通过Ref(Symbol)构建方法的反射引用再转为Expr,是符合Scala 3宏规范的标准做法。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 05:20:24