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

如何解决调用Scala quoted Expr的value*扩展方法无法构造的报错

错误原因

Expr.value/valueOrError是依赖quoted.FromExpr[T]类型类的扩展方法,Scala标准库仅对基础类型、字符串、元组、常见集合、样例类等内置了FromExpr实例,你使用的第三方类型ZIO[Any, Any, Any]没有默认的类型类实现,因此编译器无法找到对应的扩展方法,触发编译错误。

解决方法

方案1:运行期取值(推荐,适配全场景)

你不需要在宏执行的编译阶段获取ZioAny实例,直接将expr嵌入到生成的代码中,在生成代码的运行阶段自然就能拿到实际值:

def evaluateNowImpl(expr: Expr[ZioAny])(using Quotes): Expr[UIO[CallGraph]] = {
  '{ 
    val runtimeZioVal = $expr 
    UIO.succeed(new CallGraph(${Expr(expr.show)}, runtimeZioVal) {}) 
  }
}

该方案对静态常量、动态运行时表达式都生效,不需要额外编写类型类实现。

方案2:自定义FromExpr[ZioAny]实例(仅适用于编译期常量场景)

如果你确实需要在宏运行的编译阶段拿到ZioAny的值(例如需要根据ZIO的结构在编译期生成不同逻辑的代码),可以自行实现对应类型类:

given FromExpr[ZioAny] with {
  def apply(expr: Expr[ZioAny])(using Quotes): Option[ZioAny] = expr match {
    // 匹配ZIO.succeed包裹的常量表达式
    case '{ ZIO.succeed[Any](constValue) } => constValue.value.map(c => ZIO.succeed(c))
    // 匹配ZIO.fail包裹的常量表达式
    case '{ ZIO.fail[Any](constValue) } => constValue.value.map(c => ZIO.fail(c))
    // 按照你的业务需求补充其他ZIO构造器、组合子的匹配逻辑
    case _ => None
  }
}

注意该方案仅能处理编译期可确定值的常量表达式,如果传入的io0是依赖运行时参数的动态表达式,expr.value会返回None,无法拿到实际值。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 08:27:06