Erlang LanguageErlang语言入门


备注

“Erlang是一种最初在爱立信计算机科学实验室开发的编程语言.OTP(开放式电信平台)是Erlang中的中间件和库的集合.Erlang / OTP已经在许多爱立信产品中进行了战斗测试,以构建强大的容错能力分布式应用程序,例如AXD301(ATM交换机).Erlang / OTP目前由爱立信的Erlang / OTP部门维护“( erlang.org

从这里开始

有关安装说明,请参阅安装主题

链接

  1. Erlang官方网站: https//www.erlang.org
  2. Erlang和Elixir的热门包管理器: http//hex.pm
  3. Erlang模式: http//www.erlangpatterns.org/

版本

发行说明发布日期
19.2 http://erlang.org/download/otp_src_19.2.readme 2016年12月14日
19.1 http://erlang.org/download/otp_src_19.1.readme 2016年9月21日
19.0 http://erlang.org/download/otp_src_19.0.readme 2016年6月21日
18.3 http://erlang.org/download/otp_src_18.3.readme 2016年3月15日
18.2.1 http://erlang.org/download/otp_src_18.2.1.readme 2015年12月18日
18.2 http://erlang.org/download/otp_src_18.2.readme 二零一五年十二月十六日
18.1 http://erlang.org/download/otp_src_18.1.readme 2015年9月22日
18.0 http://erlang.org/download/otp_src_18.0.readme 2015年6月24日
17.5 http://erlang.org/download/otp_src_17.5.readme 2015-04-01
17.4 http://erlang.org/download/otp_src_17.4.readme 情节中字
17.3 http://erlang.org/download/otp_src_17.3.readme 2014年9月17日
17.1 http://erlang.org/download/otp_src_17.1.readme 2014年6月24日
17.0 http://erlang.org/download/otp_src_17.0.readme 2014年4月7日
R16B03-1 http://erlang.org/download/otp_src_R16B03-1.readme 2014年1月23日
R16B03 http://erlang.org/download/otp_src_R16B03.readme 2013年12月9日
R16B02 http://erlang.org/download/otp_src_R16B02.readme 2013年9月17日
R16B01 http://erlang.org/download/otp_src_R16B01.readme 2013年6月18日
R16B http://erlang.org/download/otp_src_R16B.readme 2013年2月25日

功能

功能是一组指令,它们组合在一起。这些分组指令一起执行某些任务。在erlang中,所有函数在调用时都会返回一个值。

下面是一个添加两个数字的函数示例

add(X, Y)-> X + Y.
 

此函数使用X和Y值执行添加操作并返回结果。功能可以如下使用

add(2,5).
 

函数声明可以由多个子句组成,用分号分隔。每个子句中的参数都通过模式匹配来评估。如果Argument是Form中的元组,则以下函数将返回'tuple':{test,X}其中X可以是任何值。它将返回'list',如果Argument是表格[“test”,X]中长度为2的列表,并且在任何其他情况下它将返回'{error,“Reason”}':

function({test, X}) -> tuple;
function(["test", X]) -> list;
function(_) -> {error, "Reason"}.
 

如果参数不是元组,则将评估第二个子句。如果参数不是列表,则将评估第三个子句。

函数声明可以包含所谓的“Guards”或“Guard Sequences”。这些Guards是限制函数求值的表达式。只有当所有Guard表达式都产生真值时,才会执行带有Guards的函数。多个警卫可以用分号分隔。

function_name(Argument) when Guard1; Guard2; ... GuardN -> (...).
 

仅当Guard Sequence为true时,才会评估函数'function_name'。只有当参数X 在适当的范围内(0..15)时,folllwing函数才会返回true:

in_range(X) when X>=0; X<16 -> true;
in_range(_) -> false.
 

你好,世界

在Erlang中编写“hello world”应用程序时,您需要了解两件事:

  1. 源代码使用您选择的文本编辑器以erlang编程语言编写
  2. 然后在erlang虚拟机中执行该应用程序。在这个例子中,我们将通过erlang shell与erlang VM进行交互。

首先是应用程序源代码:

创建一个包含以下内容的新文件hello.erl

-module(hello).
-export([hello_world/0]).

hello_world() ->
  io:format("Hello, World!~n", []).
 

让我们快速看看这意味着什么:

  • -module(hello). 所有erlang函数都存在于模块中 。然后使用模块构建应用程序,这是一组模块。第一行是识别这个模块,即hello 。可以将模块与Java的进行比较
  • -export([hello_world/0]). 告诉编译器哪些函数变为“公共”(与OO语言相比),以及相关函数的arity 。 arity是函数所使用的参数数量。因为在erlang中,具有1个参数的函数被视为与具有2个参数的函数不同的函数,即使名称可能完全相同。也就是说, hello_world/0 是一个完全不同于hello_world/1 函数。
  • hello_world() 这是函数的名称。 -> 表示转换到函数的实现(正文)。这可以理解为“hello_world()定义为......”。请注意, hello_world() (无参数)由VM中的hello_world/0 标识, hello_world(Some_Arg)hello_world/1
  • io:format("Hello, World!~n", []) 从模块io ,调用函数format/2 函数,这是标准输出的函数。 ~n 是格式说明符,表示打印新行。 [] 是由输出字符串中的格式说明符指示的要打印的变量列表,在这种情况下没有任何内容。
  • 所有erlang语句必须以a结尾. (点)。

在Erlang中,返回函数中最后一个语句的结果。

现在,让我们运行我们的应用程序:

从与文件hello.erl 文件相同的目录启动erlang shell:

$ erl

你应该得到一个看起来像这样的提示(你的版本可能会有所不同):

Eshell V8.0  (abort with ^G)
1>
 

现在输入以下命令:

1> c(hello).
{ok,hello}
2> hello:hello_world().
Hello, World!
ok
 

让我们逐个浏览每一行:

  • c(hello) - 这个命令调用一个原子hello 的函数c 。这有效地告诉Erlang找到文件hello.erl ,将其编译成一个模块(将在目录中生成一个名为hello.beam 的文件)并将其加载到环境中。
  • {ok, hello} - 这是调用上面的函数c 的结果。它是一个包含原子ok 和原子hello 的元组。 Erlang函数通常返回{ok, Something}{error, Reason}
  • hello:hello_world() - 它从模块hello 调用函数hello_world()
  • Hello, World! - 这就是我们的功能打印。
  • ok - 这是我们的函数返回的。由于Erlang是一种函数式编程语言,因此每个函数都返回一些东西在我们的例子中,即使我们没有在hello_world() 返回任何内容,该函数中的最后一次调用是io:format(...) 并且该函数返回ok ,这又是我们的函数返回的。

列表理解

列表推导是一种语法结构,用于根据现有列表创建列表。
在erlang中,列表理解的形式为[Expr || Qualifier1, ..., QualifierN]
限定符是生成器Pattern <- ListExpr 或过滤器,如integer(X) ,其truefalse

以下示例显示了具有一个生成器和两个过滤器的列表推导。

[X || X <- [1,2,a,3,4,b,5,6], integer(X), X > 3].
 

结果是一个只包含大于3的整数的列表。

[4,5,6]
 

模块

erlang模块是一个将几个功能组合在一起的文件。此文件通常具有.erl 扩展名。

名为hello.erl “Hello World”模块如下所示

-module(hello).
-export([hello_world/0]).

hello_world() ->
  io:format("Hello, World!~n", []).
 

在该文件中,需要声明模块名称。如第1行中所示.erl 扩展名之前的模块名称和文件名必须相同。

模式匹配

erlang中最常见的操作之一是模式匹配。它在为变量,函数声明和控制流结构(如casereceive 语句)赋值时使用。模式匹配操作至少需要2个部分:模式和模式匹配的术语。

erlang中的变量赋值如下所示:

X = 2.
 

在大多数编程语言中,此操作的语义很简单:将值( 2 )绑定到您选择的名称(变量 - 在本例中为X )。 Erlang的方法略有不同:将左侧( X )的图案与右侧的图案( 2 )匹配。在这种情况下,效果是相同的:变量X 现在绑定到值2 。但是,通过模式匹配,您可以执行更多结构化分配。

{Type, Meta, Doc} = {document, {author, "Alice"}, {text, "Lorem Ipsum"}}.
 

通过分析右手侧项的结构,并将左侧的所有变量应用于该项的适当值,使得左侧等于右侧,来执行该匹配操作。在此示例中, Type 绑定到术语: documentMeta to {author, "Alice"}Doc to {text, "Lorem Ipsum"} 。在此特定示例中,变量: TypeMetaDoc 被假定为未绑定 ,因此可以使用每个变量。

也可以使用绑定变量构建模式匹配。

Identifier = error.
 

变量Identifier 现在绑定到值error 。以下模式匹配操作起作用,因为结构匹配,并且绑定变量Identifier 具有与该术语的适当右侧部分相同的值。

{Identifier, Reason} = {error, "Database connection timed out."}.
 

当右手侧项和左手侧模式之间存在不匹配时,模式匹配操作失败。以下匹配将失败,因为Identifier 绑定到值error ,右侧术语没有适当的表达式。

{Identifier, Reason} = {fail, "Database connection timed out."}.
> ** exception error: no match of right hand side value {fail,"Database ..."}
 

启动和停止Erlang Shell

启动Erlang shell

在UNIX系统上,使用命令erl 从命令提示符启动Erlang shell

例:

$ erl
Erlang/OTP 18 [erts-7.0] [source] [64-bit] [smp:8:8] [async-threads:10] [hipe] [kernel-poll:false]

Eshell V7.0  (abort with ^G)
1> 
 

启动shell时显示的文本告诉您有关正在运行的Erlang版本的信息以及有关erlang系统的其他有用信息。

要在Windows上启动shell,请单击Windows开始菜单中的Erlang图标。

停止Erlang shell

对于erlang shell的受控退出,请键入:

Erlang/OTP 18 [erts-7.0] [source] [64-bit] [smp:8:8] [async-threads:10] [hipe] [kernel-poll:false]

Eshell V7.0  (abort with ^G)
1> q().
 

您也可以通过在UNIX系统上按Ctrl + C或在Windows上按Ctrl + Break退出Erlang shell,这会带您进入以下提示:

Erlang/OTP 18 [erts-7.0] [source] [64-bit] [smp:8:8] [async-threads:10] [hipe] [kernel-poll:false]

Eshell V7.0  (abort with ^G)
1> 
BREAK: (a)bort (c)ontinue (p)roc info (i)nfo (l)oaded
       (v)ersion (k)ill (D)b-tables (d)istribution
 

如果您然后按a(中止),您将直接退出shell。

退出erlang shell的其他方法是: init:stop()q()erlang:halt()