【问题标题】:Elixir quote/unquote and macros behaviourElixir 引用/取消引用和宏行为
【发布时间】:2016-07-22 23:07:54
【问题描述】:

我有两个版本的__using__,但是,第一个版本的行为与我预期的不同。这段代码不能正常工作(实际上它并没有导入任何东西)。

defmodule SomeModule do
  defmacro __using__(opts \\ []) do
    quote do
      opts = unquote(opts)
      if Keyword.has_key?(opts, :my_key) && opts[:my_key] == 3 do
        import MyModuleOne
      else
        import MyModuleTwo
      end
    end
  end
end

这是工作版本,但是,我不喜欢有两个单独的 quote 部分。

defmodule SomeModule do
  defmacro __using__(opts \\ []) do
    if Keyword.has_key?(opts, :my_key) && opts[:my_key] == 3 do
      quote do
        import MyModuleOne
      end
    else
      quote do
        import MyModuleTwo
      end
    end
  end
end

第一个应该如何重写才能正常工作?

【问题讨论】:

    标签: macros elixir


    【解决方案1】:

    这是一个棘手的问题!我花了一段时间才弄清楚原因......

    在说明原因之前,让我向您保证,您的宏是完全有效的,并且 Elixir 的工作原理与 您所说的完全一样。

    我尝试扩展您发布的两个宏并得到相同的结果,即正在导入正确的内容。但是为什么它没有像你预期的那样工作?

    原因如下,

    重要的是要注意 import/2 是词法

    来自import的文档

    让我给你看两个例子

    iex(1)> import Enum, only: [into: 2]
    Enum
    iex(2)> into [a: 1], %{}
    %{a: 1}
    iex(3)>
    

    还有……

    iex(1)> if true do
    ...(1)>   import Enum, only: [into: 2]
    ...(1)> end
    Enum
    iex(2)> into [a: 1], %{}
    ** (CompileError) iex:2: undefined function into/2
    

    导入仅在您编写的子句内生效:)

    【讨论】:

    • 嗯,你是对的 :) 用其他功能检查过 - 确认 :)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-22
    相关资源
    最近更新 更多