Elixir語言中 Macro.expand_once
相關用法介紹如下。
用法:
expand_once(ast, env)
接收一個 AST 節點並展開一次。
展開以下內容:
- 宏(本地或遠程)
- 別名被擴展(如果可能)並返回原子
- 編譯環境宏(
__CALLER__/0
__DIR__/0
__ENV__/0
__MODULE__/0
- 模塊屬性閱讀器(
@foo
)
如果表達式無法展開,則返回表達式本身。這個函數不遍曆AST,隻展開根節點。
隻執行一次擴展。勾選expand_once/2
進行擴展,直到節點不能再擴展。expand/2
例子
在下麵的示例中,我們有一個宏,它生成一個帶有名為name_length
的函數的模塊,該函數返回模塊名稱的長度。此函數的值將在編譯時計算,而不是在運行時計算。
考慮下麵的實現:
defmacro defmodule_with_length(name, do: block) do
length = length(Atom.to_charlist(name))
quote do
defmodule unquote(name) do
def name_length, do: unquote(length)
unquote(block)
end
end
end
當像這樣調用時:
defmodule_with_length My.Module do
def other_function, do: ...
end
編譯將失敗,因為引用時的My.Module
不是原子,而是語法樹,如下所示:
{:__aliases__, [], [:My, :Module]}
也就是說,我們需要將上麵的別名節點擴展為一個原子,以便我們可以檢索它的長度。擴展節點並不簡單,因為我們還需要擴展調用者別名。例如:
alias MyHelpers, as: My
defmodule_with_length My.Module do
def other_function, do: ...
end
最終的模塊名稱將是 MyHelpers.Module
而不是 My.Module
。使用
時,會考慮此類別名。本地和遠程宏也被擴展。我們可以重寫上麵的宏來使用這個函數:Macro.expand/2
defmacro defmodule_with_length(name, do: block) do
expanded = Macro.expand(name, __CALLER__)
length = length(Atom.to_charlist(expanded))
quote do
defmodule unquote(name) do
def name_length, do: unquote(length)
unquote(block)
end
end
end
相關用法
- Elixir Macro.escape用法及代碼示例
- Elixir Macro.Env.fetch_alias用法及代碼示例
- Elixir Macro.prewalk用法及代碼示例
- Elixir Macro.generate_unique_arguments用法及代碼示例
- Elixir Macro.quoted_literal?用法及代碼示例
- Elixir Macro.Env.required?用法及代碼示例
- Elixir Macro.validate用法及代碼示例
- Elixir Macro.Env.prepend_tracer用法及代碼示例
- Elixir Macro.camelize用法及代碼示例
- Elixir Macro.operator?用法及代碼示例
- Elixir Macro.var用法及代碼示例
- Elixir Macro.unescape_string用法及代碼示例
- Elixir Macro.unique_var用法及代碼示例
- Elixir Macro.to_string用法及代碼示例
- Elixir Macro.Env.lookup_import用法及代碼示例
- Elixir Macro.prewalker用法及代碼示例
- Elixir Macro.postwalker用法及代碼示例
- Elixir Macro.underscore用法及代碼示例
- Elixir Macro.generate_arguments用法及代碼示例
- Elixir Macro.Env.has_var?用法及代碼示例
- Elixir Macro.decompose_call用法及代碼示例
- Elixir Macro.Env用法及代碼示例
- Elixir Macro.update_meta用法及代碼示例
- Elixir Macro.unpipe用法及代碼示例
- Elixir Macro用法及代碼示例
注:本文由純淨天空篩選整理自elixir-lang.org大神的英文原創作品 Macro.expand_once(ast, env)。非經特殊聲明,原始代碼版權歸原作者所有,本譯文未經允許或授權,請勿轉載或複製。