Elixir语言中 Kernel.@expr
相关用法介绍如下。
用法:
@expr
(宏)
模块属性一元运算符。
读取和写入当前模块中的属性。
属性的典型示例是注释模块实现了 OTP 行为,例如
:GenServer
defmodule MyServer do
@behaviour GenServer
# ... callbacks ...
end
默认情况下,Elixir 支持 Erlang 支持的所有模块属性,但也可以使用自定义属性:
defmodule MyServer do
@my_data 13
IO.inspect(@my_data)
#=> 13
end
与 Erlang 不同,这些属性默认不存储在模块中,因为 Elixir 中通常使用自定义属性来存储在编译时可用的临时数据。可以使用
将自定义属性配置为更接近 Erlang。Module.register_attribute/3
重要提示:库和框架应考虑使用下划线作为私有模块属性的前缀,例如@_my_data
,以便代码完成工具不会在建议和提示中显示它们。
最后,注意属性也可以在函数内部读取:
defmodule MyServer do
@my_data 11
def first_data, do: @my_data
@my_data 13
def second_data, do: @my_data
end
MyServer.first_data()
#=> 11
MyServer.second_data()
#=> 13
需要注意的是,读取属性会获取其当前值的快照。换句话说,该值是在编译时读取的,而不是在运行时读取的。检查
模块是否有其他函数来操作模块属性。Module
注意力!同一属性的多个引用
如上所述,每次读取模块属性时,都会对其当前值进行快照。因此,如果您在模块属性中存储较大的值(例如,在模块属性中嵌入外部文件),则应避免多次引用同一属性。例如,不要这样做:
@files %{
example1: File.read!("lib/example1.data"),
example2: File.read!("lib/example2.data")
}
def example1, do: @files[:example1]
def example2, do: @files[:example2]
在上文中,对@files
的每个引用都可能在end-up 中带有整个@files
模块属性的完整且单独的副本。相反,在私有函数中引用一次模块属性:
@files %{
example1: File.read!("lib/example1.data"),
example2: File.read!("lib/example2.data")
}
defp files(), do: @files
def example1, do: files()[:example1]
def example2, do: files()[:example2]
注意力!编译时依赖
请记住对其他模块的引用,即使在模块属性中,也会生成对所述模块的编译时依赖项。
例如,采用这种常见模式:
@values [:foo, :bar, :baz]
def handle_arg(arg) when arg in @values do
...
end
虽然上面没问题,但想象一下,如果您在模块属性中有实际的模块名称,如下所示:
@values [Foo, Bar, Baz]
def handle_arg(arg) when arg in @values do
...
end
上面的代码将定义对模块 Foo
、 Bar
和 Baz
的编译时依赖,如果它们中的任何一个发生变化,当前模块将不得不重新编译。在这种情况下,最好完全避免使用模块属性:
def handle_arg(arg) when arg in [Foo, Bar, Baz] do
...
end
相关用法
- Elixir Kernel.SpecialForms.case用法及代码示例
- Elixir Kernel.round用法及代码示例
- Elixir Kernel.left / right用法及代码示例
- Elixir Kernel.put_in用法及代码示例
- Elixir Kernel.tl用法及代码示例
- Elixir Kernel.left - right用法及代码示例
- Elixir Kernel.tuple_size用法及代码示例
- Elixir Kernel.defexception用法及代码示例
- Elixir Kernel.to_charlist用法及代码示例
- Elixir Kernel.base ** exponent用法及代码示例
- Elixir Kernel.left !== right用法及代码示例
- Elixir Kernel.if用法及代码示例
- Elixir Kernel.spawn_monitor用法及代码示例
- Elixir Kernel.to_string用法及代码示例
- Elixir Kernel.length用法及代码示例
- Elixir Kernel.first..last用法及代码示例
- Elixir Kernel.SpecialForms.%{}用法及代码示例
- Elixir Kernel.SpecialForms.for用法及代码示例
- Elixir Kernel.then用法及代码示例
- Elixir Kernel.spawn用法及代码示例
- Elixir Kernel.defmodule用法及代码示例
- Elixir Kernel.SpecialForms.quote用法及代码示例
- Elixir Kernel.left > right用法及代码示例
- Elixir Kernel.binding用法及代码示例
- Elixir Kernel.sigil_r用法及代码示例
注:本文由纯净天空筛选整理自elixir-lang.org大神的英文原创作品 Kernel.@expr。非经特殊声明,原始代码版权归原作者所有,本译文未经允许或授权,请勿转载或复制。