`use` 和 `@before_compile` 有什么区别?

Fen*_*eng 3 metaprogramming elixir

use和 和有@before_compile什么区别?两者都可用于将一些代码注入当前模块。

Dog*_*ert 6

一个主要区别是,在模块内__using__调用时,调用in 的代码并注入返回值use,而__before_compile__在模块内直接执行所有代码后,即在编译模块之前,调用并注入返回值。

一个简单的程序来演示差异:

defmodule When do
  defmacro __using__(_) do
    IO.inspect :using
    __CALLER__.module |> Module.definitions_in |> IO.inspect
    quote do end
  end

  defmacro __before_compile__(_) do
    IO.inspect :before_compile
    __CALLER__.module |> Module.definitions_in |> IO.inspect
    quote do end
  end
end

defmodule Main do
  @before_compile When
  use When
  IO.puts "added `@before_compile` and `use`"
  def add(x, y), do: x + y
end
Run Code Online (Sandbox Code Playgroud)

输出:

:using
[]
added `@before_compile` and `use`
:before_compile
[add: 2]
Run Code Online (Sandbox Code Playgroud)

ExUnit用于@before_compile定义一个返回所有测试的函数,使 ExUnit 运行程序可以获取并运行所有测试。