[英]What does “@” do in Elixir?
我一直在查看一些编码解决方案,它们显示了“@”符号; 但是,我似乎无法通过查看文档来真正弄清楚该符号的作用。
@ 符号在 Elixir 中有什么作用,为什么它很重要?
下面是一个例子:
defmodule RNATranscription do
@dna_nucleotide_to_rna_nucleotide_map %{
# `G` -> `C`
71 => 67,
# `C` -> `G`
67 => 71,
# `T` -> `A`
84 => 65,
# `A` -> `U`
65 => 85
}
@doc """
Transcribes a character list representing DNA nucleotides to RNA
## Examples
iex> RNATranscription.to_rna('ACTG')
'UGAC'
"""
@spec to_rna([char]) :: [char]
def to_rna(dna) do
dna
|> Enum.map(&get_rna_for_dna/1)
end
defp get_rna_for_dna(dna_nucleotide) do
@dna_nucleotide_to_rna_nucleotide_map[dna_nucleotide]
end
end
Elixir 中的@
符号表示 模块属性,这是有用的编译时设置。 您经常在可能将类常量放入 OO 语言的地方看到它们。
然而,模块属性比您在面向对象语言中可能发现的更微妙。 以下是一些重要的要点:
它们不使用=
来分配值(如果您习惯于在 OO-land 中定义类常量,您可能会习惯这样做)。 语法更像是function input
,其中删除了可选的括号。
模块属性可以在整个模块中多次重新定义。 你会经常看到@doc
属性注释它@spec
的函数, @spec
注释函数输入/输出,或者在测试内部用@tag
更改输入到它@tag
的测试。 这可以提供一种有用的方法来将大值排除在函数逻辑之外以提高可读性。
模块属性可以累积。 通常,属性的每个实例都会重新分配其值,但是如果您在注册属性时设置了accumulate: true
,那么后续定义将进行累加,以便读取该属性将返回所有累加值。 从文档页面:
defmodule MyModule do
Module.register_attribute(__MODULE__, :custom_threshold_for_lib, accumulate: true)
@custom_threshold_for_lib 10
@custom_threshold_for_lib 20
@custom_threshold_for_lib #=> [20, 10]
end
defmodule Trouble do
@my_value System.fetch_env("BOOM") # <-- don't do this!
end
如果您尝试这样做,更新版本的 Elixir 将显示警告(并且某些值,例如捕获的函数,将引发错误),因此作为一般经验法则,最好保持模块属性简单和静态。
这是 模块属性的语法:
Elixir 中的模块属性有三个用途:
- 它们用于注释模块,通常包含用户或 VM 使用的信息。
- 它们作为常量工作。
- 它们用作编译期间使用的临时模块存储。
属性由编译器在编译时读取,因此无法在运行时访问或更改。 在运行时,它们将被编译器评估的任何内容替换。
在您的情况下,此功能:
defp get_rna_for_dna(dna_nucleotide) do
@dna_nucleotide_to_rna_nucleotide_map[dna_nucleotide]
end
有效地编译为:
defp get_rna_for_dna(dna_nucleotide) do
%{
71 => 67,
67 => 71,
84 => 65,
65 => 85
}[dna_nucleotide]
end
@spec
用于定义类型规范, @doc
用于文档。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.