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

Elixir中map即便使用Macro.escape也无法正常unquote问题咨询

问题原因

你连续两次使用了Macro.escape转义map值,导致最终注入到代码中的是「map的AST结构的AST」,而非实际可运行的map值:

  • 第一次转义:调用use Foo时,你主动对%{:correct => true}做了Macro.escape处理,得到的是map对应的AST结构{:%{}, [], [correct: true]}
  • 第二次转义:在__using__宏的Keyword.get逻辑中,你对传入的已经是AST的attrs值又做了一次Macro.escape,相当于把AST结构再次转义成了新的AST
    最终unquote执行后,输出的就是第一次转义得到的AST结构,而非你预期的map值。
正确实现方式

最合理的方案是把转义逻辑统一封装在宏内部,使用方不需要感知转义操作,修改后代码如下:

defmodule Foo do
  defmacro __using__(options) do
    attrs = Keyword.get(options, :attrs, %{})
    # 仅在宏内部统一做一次转义
    escaped_attrs = Macro.escape(attrs)
    quote do
      def show, do: IO.inspect(unquote(escaped_attrs))
    end
  end
end

defmodule MacroFix do
  use Foo,
    # 直接传原始map即可,不需要额外转义
    attrs: %{correct: false}
end

运行验证:

iex> MacroFix.show
%{correct: false}
%{correct: false}

如果需要保留使用方自行转义的逻辑,只需要删除__using__中Keyword.get的第二个参数里的Macro.escape即可,该方案会提高宏的使用门槛,不推荐。

内容的提问来源于stack exchange,提问作者Guilherme Torres Castro

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.20 16:36:07