Erlang atom的简单解释

yay*_*ayu 3 erlang

我正在学习 Erlang 并试图理解原子的概念。我知道 Python:用简单的术语或与 Python 类似的方式对这些“原子”有什么好的解释。到目前为止,我的理解是类型就像一个字符串但没有字符串操作?

tko*_*wal 6

文档说:

一个原子是一个文字,一个带有名字的常量。

有时,您有多种选择,您想从中进行选择。例如,在 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_1request_type_2stop。它被称为模式匹配。

服务器也使用原子作为返回值。ok原子意味着,一切顺利。_匹配所有内容,因此万一那个简单的服务器收到意想不到的东西,它会退出 tuple {error, Reason},原因也是 atom bad_request

布尔值truefalse也原子。您可以使用如下函数子句构建逻辑函数:

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 中看到。