當前位置: 首頁>>代碼示例 >>用法及示例精選 >>正文


Elixir Kernel.use用法及代碼示例


Elixir語言中 Kernel.use 相關用法介紹如下。

用法:

use(module, opts \\ [])
(宏)

在當前上下文中使用給定的模塊。

調用時:

use MyModule, some: :options

調用MyModule 模塊中的__using__/1 宏,將傳遞給use 的第二個參數作為其參數。由於__using__/1 是一個宏,所有常用的宏規則都適用,並且它的返回值應該是引用的代碼,然後插入到調用 use/2 的地方。

例子

例如,要使用 Elixir 提供的 ExUnit 框架編寫測試用例,開發人員應該 use ExUnit.Case 模塊:

defmodule AssertionTest do
  use ExUnit.Case, async: true

  test "always pass" do
    assert true
  end
end

在此示例中,Elixir 將調用 ExUnit.Case 模塊中的 __using__/1 宏,並將關鍵字列表 [async: true] 作為其參數。

換句話說, use/2 轉換為:

defmodule AssertionTest do
  require ExUnit.Case
  ExUnit.Case.__using__(async: true)

  test "always pass" do
    assert true
  end
end

其中 ExUnit.Case 定義__using__/1 宏:

defmodule ExUnit.Case do
  defmacro __using__(opts) do
    # do something with opts
    quote do
      # return some code to inject in the caller
    end
  end
end

最佳實踐

__using__/1 通常在需要將某些狀態(通過模塊屬性)或回調(如 @before_compile ,請參閱 Module 的文檔以獲取更多信息)設置到調用者時使用。

__using__/1 也可用於別名、要求或導入來自不同模塊的函數:

defmodule MyModule do
  defmacro __using__(_opts) do
    quote do
      import MyModule.Foo
      import MyModule.Bar
      import MyModule.Baz

      alias MyModule.Repo
    end
  end
end

但是,如果 __using__/1 所做的隻是導入、別名或要求模塊本身,則不要提供。例如,避免這種情況:

defmodule MyModule do
  defmacro __using__(_opts) do
    quote do
      import MyModule
    end
  end
end

在這種情況下,開發人員應該直接導入或別名模塊,以便他們可以根據需要自定義這些模塊,而不需要 use/2 後麵的間接。

最後,開發人員還應避免在 __using__/1 回調中定義函數,除非這些函數是先前定義的 @callback 的默認實現,或者是要被覆蓋的函數(參見 defoverridable/1 )。即使在這些情況下,定義函數也應視為"last resort"。

如果您想為用戶模塊提供一些現有函數,請將其定義在將相應導入的模塊中;例如, ExUnit.Case 沒有在調用 use ExUnit.Case 的模塊中定義 test/3 宏,但它定義了 ExUnit.Case.test/3 並在使用時將其導入調用者。

相關用法


注:本文由純淨天空篩選整理自elixir-lang.org大神的英文原創作品 Kernel.use(module, opts \\ [])。非經特殊聲明,原始代碼版權歸原作者所有,本譯文未經允許或授權,請勿轉載或複製。