我正在学习 Erlang 并试图理解原子的概念。我知道 Python:用简单的术语或与 Python 类似的方式对这些“原子”有什么好的解释。到目前为止,我的理解是类型就像一个字符串但没有字符串操作?
文档说:
一个原子是一个文字,一个带有名字的常量。
有时,您有多种选择,您想从中进行选择。例如,在 C 中,您有enum
:
enum Weekday { Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday };
Run Code Online (Sandbox Code Playgroud)
在 C 中,它实际上是一个整数,但您可以在代码中将它用作选项之一。Erlang 中的原子在模式匹配中非常有用。让我们考虑非常简单的服务器:
loop() ->
receive
{request_type_1, Request} ->
handle_request_1(Request),
loop();
{request_type_2, Request} ->
handle_request_2(Request),
loop();
{stop, Reason} ->
{ok, Reason};
_ ->
{error, bad_request}
end.
Run Code Online (Sandbox Code Playgroud)
您的服务器接收消息,这是两个元素元组,并使用原子来区分不同类型的请求:request_type_1
、request_type_2
和stop
。它被称为模式匹配。
服务器也使用原子作为返回值。ok
原子意味着,一切顺利。_
匹配所有内容,因此万一那个简单的服务器收到意想不到的东西,它会退出 tuple {error, Reason}
,原因也是 atom bad_request
。
布尔值true
和false
也原子。您可以使用如下函数子句构建逻辑函数:
and(true, true) ->
true;
and(_, _) ->
false.
or(false, false) ->
false;
or(_, _) ->
true.
Run Code Online (Sandbox Code Playgroud)
(它有点过于简单化了,因为你可以这样调用它:or(atom1, atom2)
它会返回true
,但它只是为了说明。)
Erlang 中的模块名称也是原子,因此您可以将模块名称绑定到变量并调用它,例如在 Erlang shell 中键入:
io:format("asdf").
Variable = io.
Variable:format("asdf").
Run Code Online (Sandbox Code Playgroud)
您不应该将原子用作字符串,因为它们不会被垃圾收集。如果您开始动态创建它们,则可能会耗尽内存。它们应该只在有固定数量的选项时使用,您可以手动输入代码。当然,您可以根据需要多次使用同一个原子,因为它始终指向内存中的同一点(原子表)。
它们比 C 枚举更好,因为该值在运行时是已知的。因此,在调试 C 代码时,您会在调试器中看到1
而不是Tuesday
。使用原子没有那个缺点,你会tuesday
在你的代码和 Erlang shell 中看到。