Erlang 是一种功能性编程语言,旨在构建可扩展和容错的系统,特别是在并发和分布式应用程序领域。它最初由爱立信在1980年代末开发,目的是创建强大的电信系统。Erlang 的独特特性包括对轻量级进程的支持、消息传递并发、热代码交换以及对可靠性的强烈强调。如今,它广泛应用于需要高可用性和分布式系统的行业,如电信、消息应用和数据库系统。
Erlang 是在1980年代末由 Joe Armstrong、Robert Virding 和 Mike Williams 在爱立信创建的,主要是为了满足电信行业的需求。该语言的开发旨在促进构建大规模、容错的系统,能够同时管理多个呼叫和连接。
在1990年代初,爱立信认识到 Erlang 在电信之外的潜力。到1998年,Erlang 被发布为开源,这使得更广泛的开发者社区能够为其发展做出贡献。开源运动导致了 BEAM 虚拟机的开发,该虚拟机执行 Erlang 代码,并且自那时以来已经演变为支持其他语言。
Erlang 目前由 Erlang/OTP 团队维护,并拥有一个专注的社区。Erlang 的发布周期变得更加一致,定期更新和改进专注于性能、新特性和增强文档。该语言还激发了 Elixir 的发展,Elixir 是一种现代编程语言,运行在 Erlang 虚拟机上,并结合了许多 Erlang 的原则,同时提供了额外的特性。
Erlang 主要是一种函数式语言,这意味着函数是第一类公民,可以像变量一样传递。
double(X) -> X * 2.
Erlang 的轻量级进程使得可以创建成千上万的并发进程,而不会产生显著的开销。
spawn(fun() -> io:format("Hello from a process!~n") end).
Erlang 中的进程通过消息传递进行通信,这允许在没有共享状态的情况下安全地进行通信。
Pid = spawn(fun() -> receive
{msg, Content} -> io:format("Received: ~s~n", [Content])
end end),
Pid ! {msg, "Hello!"}.
Erlang 使用模式匹配,这是一种强大的特性,可以使代码清晰简洁。
match(X) when X > 0 -> io:format("Positive number: ~B~n", [X]);
match(X) -> io:format("Non-positive number: ~B~n", [X]).
Erlang 通过其“让它崩溃”的哲学支持容错,允许进程失败并重新启动,而不影响系统。
start_process() ->
spawn(fun() -> crash() end).
Erlang 允许开发者在运行的系统中更改代码而无需停止它们。
%% 旧版本
-module(example).
-export([hello/0]).
hello() -> io:format("Old Version~n").
%% 新版本
-module(example).
-export([hello/0]).
hello() -> io:format("New Version~n").
Erlang 中的数据是不可变的,这导致更少的错误和更容易推理代码。
List = [1, 2, 3],
NewList = [4 | List].
Erlang 具有允许在不同节点之间轻松分布进程的特性。
net_adm:start() ->
net_adm:ping('other_node@hostname').
Erlang 支持记录类型以创建结构化数据类型。
-record(person, {name, age}).
Person = #person{name="Alice", age=30}.
Erlang 允许使用列表推导简洁地生成和操作列表。
Squares = [X*X || X <- [1,2,3]].
Erlang 在 BEAM 虚拟机上执行,该虚拟机旨在运行并发和容错应用程序。BEAM 优化性能,并允许热代码交换等特性。
有几个用于 Erlang 的开发环境,其中 Emacs 和 IntelliJ IDEA(带 Erlang 插件)是最受欢迎的。其他值得注意的工具包括专门针对 Erlang 的编辑器,如 Erlide。
要创建一个 Erlang 项目,传统上使用 rebar3
工具来管理依赖关系和构建。例如,要创建一个新项目,可以执行:
rebar3 new app myapp
然后,可以使用以下命令构建项目:
rebar3 compile
Erlang 广泛应用于电信、消息系统和实时应用程序。著名的应用包括:
Erlang 的主要优势在于其并发模型和容错性,这使其与以下语言区分开来:
将代码翻译到 Erlang 及其外部可能很复杂,因为其独特的范式。像 erl2cpp
这样的工具存在于某些翻译中,但没有广泛的自动化工具适用于所有语言。手动翻译可能涉及: