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)。非经特殊声明,原始代码版权归原作者所有,本译文未经允许或授权,请勿转载或复制。