erlang中文基础教程.pdf

上传人:asd****56 文档编号:70322798 上传时间:2023-01-19 格式:PDF 页数:24 大小:315.55KB
返回 下载 相关 举报
erlang中文基础教程.pdf_第1页
第1页 / 共24页
erlang中文基础教程.pdf_第2页
第2页 / 共24页
点击查看更多>>
资源描述

《erlang中文基础教程.pdf》由会员分享,可在线阅读,更多相关《erlang中文基础教程.pdf(24页珍藏版)》请在得力文库 - 分享文档赚钱的网站上搜索。

1、Erlang 编程(第一部分)1 顺序编程1.1 The Erlang Shell大多数操作系统都有一个命令行交互环境或者一个 shell,对于 UNIX 和 LINUX 尤其是这样。Windows也有自己的命令行模式。Erlang 也同样有自己的 shell,我们可以直接在里面编写代码和运行我们编写的程序,并在其中看到我们的输出情况。我们能够在多种操作系统上运行 Erlang 的 shell,一般来说在我们所使用的操作系统的命令行中输入erl 就可以了,我们将可能看到下面的提示:%erlErlang(BEAM)emulator version 5.2 source hipeEshell V5

2、.2 (abort with G)1 “现在我们输入 2+5.”,(注意最后有一个英文句号,并不包括引号哈)1 2+5.72 在Windows 中,我们还可以通过双击 Erlang shell 的图标来启动 Erlang shell。你现在注意到了Erlang shell 的命令行前面都有一个标号(例如 1 2),并且下面正确的输出了我“们的答案 7”!同样我们注意到我们的输入的最后有一个英文的句号,这是在我们最终按下回车之前的最后一个字符。如果我们写在shell 中的东西有什么错误,我们可以使用退格键进行删除,于是,我们推想我们可以使用其他shell 下的一些常用的编辑命令,而事实上确实是这

3、样的,以后我们使用到的时候再介 绍。现在我们尝试一下稍微复杂一点的运算:2(42+77)*66/3.2618.00 “”“我们现在使用了一些 复杂一点 的运算符号*”“和/”,分别表示乘法运算和除法运算。除此之外还支持其 他一些运算符号,我们在以后使用到的时候再介绍。我们打算关闭Elrang 系统,则需要在Erlang shell 中键入 Ctrl+C,我们将看到下面的输出:BREAK:(a)bort(c)ontinue(p)roc info(i)nfo(l)oaded (v)ersion(k)ill(D)b-tables(d)istributiona%“我们这时候键入 a”就会退出Erlan

4、g 系统。另一个方法就是键入 halt(),也可以实现退出 Erlang 系统的目的:3 halt().%1.2 Modules 和 Functions(模块和函数)一个编程语言如果只能让我们从shell 中运行代码,那么可以说这个语言的用处受到了很大的限制,至少我会感觉到不爽。这里有一个小的Erlang 程序。我们将下面的内容键入一个叫做tut.erl 的文件(这里需要注意到的是我们的tut.erl 文件应该放在 erl 程序的同一个目录下,文件名应该和模块名相同,这样Erlang 才能很好的找到我们的模块,至于编辑器随便一个支持纯文本的就可以哈)。如果我们的编辑器有一个Erlang 模式就

5、可能编写起来更加方便,并且代码的格式也会变得更加规范,但是我们也许也会产生对这些编辑器或者IDE 的强烈依赖性。下面就是我们要键入的代码:-module(tut).-export(double/1).double(X)-2*X.“不难看出,我们的程序的任务就是将输入的数字进行 乘以 2”的操作。我们后面会解释前两行的含义。我们现在来编译一下这个程序,我们在Erlang shell 中键入下面的内容:3 c(tut).ok,tut ok,tut“告诉我们编译成功的完成了。如果显示的是 error”,那么可能我们的文件位置或者键入的代码文本存在某些问题,出错信息会给我们一些提示,我们按照提示做就好

6、了,仔细的检查代码在任何时候 都是需要的:)现在我们来运行以下这个程序:4 tut:double(10).20 和预计的一样,10“的 乘以 2”之后是20(貌似是废话)。现在让我们回到最开始的两行代码。Erlang 程序一般是保存在文件中的。每个文件我们在Erlang 中称为module(模块)。第一行就是告诉我们这个模块的名字。-module(tut).“这段代码告诉我们该模块的名称为 tut”“。注意这行最后的.”符号是必不可少的。这个模块名必须和保存“这段代码的文件(后缀为 erl”“的文件)有相同的名称。所以这里我们要求了文件名必须是 tut.erl”的原因。当我们在使用另一个模块中

7、的函数时,我们使用下面的语法module_name:function_name(arguments).所以:4 tut:double(10).意味着我们从tut模块中调用一个叫做 double“的函数,并且带有参数 10”.第二行:-export(double/1).含一位模块tut中包含一个名叫 double“的函数,并且带有一个参数(就是例子中的 10”),并且这个函数可以被从模块tut“之外调用到。更深入的内容我们后面会介绍。现在回头看看上面行尾的句号.”。现在有一个稍微复杂一点的例子,是用来进行阶乘(比如 4 的阶乘就是1*2*3*4 的结果)操作的。键入下面的代码到一个新建的文本文件

8、,并命名为 tut1.erl:-module(tut1).-export(fac/1).fac(1)-1;fac(N)-N*fac(N-1).编译这个文件:5 c(tut1).ok,tut1 现在我们计算4 的阶乘:6 tut1:fac(4).24 第一部分:fac(1)-1;含义为1 的阶乘是 1.“注意到这部分最后的;”符号,它预示着下面还有这个函数的其他部分。第二部分:fac(N)-N*fac(N-1).含义是N 的阶乘等于 N 乘以N-1“的阶乘。注意这部分最后的符号.”,含义为对于该函数已经没有更多的 内容了,函数就此结束。一个函数可以有很多的参数。让我们扩展这个 tut1“”模块,

9、现在多包含一个 白痴函数:两个数的相乘:-module(tut1).-export(fac/1,mult/2).fac(1)-1;fac(N)-N*fac(N-1).mult(X,Y)-X*Y.注意到我们也扩展了-export 这行,加入了一个包含两个参数的函数 mult。编译一下:7 c(tut1).ok,tut1 试一下我们的代码是否正常工作了:8 tut1:mult(3,4).12 上面的例子使用了整数进行乘法运算,其中 N/X/Y 成为变量。注意:变量必须是以大写字母开头,否则编译会提示出错。下面的变量名就是合法的:Number,ShoeSize,Age 等。1.3 常量常量是Erla

10、ng 中的一种数据类型。常量以小写字符开头,例如:charles、centimeter、inch 等。常量仅 仅只是一个简单的名字,不想我们的变量带有自身的值。键入下面的程序到tut2.erl 文件中,该程序帮助我们将英尺转换为厘米:-module(tut2).-export(convert/2).convert(M,inch)-M/2.54;convert(N,centimeter)-N*2.54.编译并测试一下:9 c(tut2).ok,tut210 tut2:convert(3,inch).1.1811011 tut2:convert(7,centimeter).17.7800 注意我们

11、这里使用了十进制的数值(浮点类型),而并没有任何显式的的声明,但是我猜想你们是可以 应付这种情况的。看一下我们键入其他东西会发生什么情况(除了 inch 和 centimeter 之外的):13 tut2:convert(3,miles).=ERROR REPORT=8-Oct-2006:22:52:46=Error in process with exit value:function_clause,tut2,convert,3,miles,erl_eval,expr,3,erl_eval,exprs,4,shell,eval_loop,2*exited:function_clause,tu

12、t2,convert,3,miles,erl_eval,expr,3,erl_eval,exprs,4,shell,eval_loop,2*这里有两部分被称为子句的内容存在于convert 函数中,但是 miles 并不是这两部分中的其中一部分。于是Erlang 系统不能成功的匹配函数中的子句调用,于是我们就看到了上面的出错提示function_clause“”消息。上面的输出看上去是 典型的一团糟,但是经过我们认真的观察,我们可以清楚 的直到代码中到底是发生了什么。1.4 元组现在的tut2 程序并不具备一个很好的编程代码的风格。考虑下面的代码:tut2:convert(3,inch).意味

13、着3 的单位是 inches 英尺?还是3 是厘米,但是我们打算转换为英尺?所以Erlang 有一个方式让“这些东西组织为一种更容易理解的形式。我们称为元组,元组的含义为被”“和”包围着的那部分。我们可以写inch,3来表示3 英尺,和centimeter,5表示 5 厘米。现在让我们重新编写上面的转换程序(文件tut3.erl):-module(tut3).-export(convert_length/1).convert_length(centimeter,X)-inch,X/2.54;convert_length(inch,Y)-centimeter,Y*2.54.Compile and

14、 test:14 c(tut3).ok,tut315 tut3:convert_length(inch,5).centimeter,12.700016 tut3:convert_length(tut3:convert_length(inch,5).inch,5.00000 注意上面的第16 行,我们将 5 英尺转换为了厘米度量,并将其安全的转换了回去,得到了原来的值。另外这个例子还说明我们可以将一个函数的返回值作为另一个函数的参数传入。我们先在第 16 行这里停一下,考虑一下具体的执行情况。我们传入了inch,5的函数返回的结果成功的匹配了模块中的convert_length(centimet

15、er,X),原因在于前一个函数的返回是centimeter,X形式的。如果还不 够清楚,那么你可以分别执行这两个函数,仔细看看他们的返回情况。我们看了有两个部分的元组,但是元组可以有更多的部分组成,我们可以包含任何合法的 Erlang 内容。例如,为了表示城市的温度,我们写下如下代码:moscow,c,-10cape_town,f,70paris,f,28 元组有固定的内部的组成数量。我们称在元组中的东西为元素。所以元组moscow,c,-10,元素 1 为moscow,元素 2 为c,-10。这里的c 表示摄氏度,f 为华氏度。1.5 列表元组将各种元素组合在一起,我们同样也希望能够表示一串

16、某些东西。列表在 Erlang“中就是被”“和”包围起来的部分。下面就是一个关于城市和对应气温的列表的例子:moscow,c,-10,cape_town,f,70,stockholm,c,-4,paris,f,28,london,f,36 注意到这个列表很长,以致于一行不能显示完,这没有关系,Erlang 允许在非敏感的地方换行,但是在 一个常量中或者整数中换行就是不允许的。“一个非常有用的寻找列表中一部分的方法就是使用|”。在下面的 shell 中的例子可以很好的进行说明:18 First|TheRest=1,2,3,4,5.1,2,3,4,519 First.120 TheRest.2,3

17、,4,5 “我们使用|”来分开第一个列表元素与后面剩下的元素。(First“可以用来获取到值 1”,而 TheRest 可以获取到剩下的部分2,3,4,5)。另外一个例子:21 E1,E2|R=1,2,3,4,5,6,7.1,2,3,4,5,6,722 E1.123 E2.224 R.3,4,5,6,7 “从上面我们可以看到使用|”可以从列表中分离最开始的两个元素。当然,如果我们尝试获取比列表中包含的元素数量更多的元素,我们只会得到一个错误提示。但是有一个特殊情况就是获得一个没有包含任何元素的空列表。25 A,B|C=1,2.1,226 A.127 B.228 C.从上面所有的例子中,我们使用

18、了新的变量名,而没有使用已经用过的那些:First、TheRest、E1、E2、R、A、B、C。原因在于在上下文相关的地方(同一个作用域),我们的变量只能 赋值一次。我们稍后会回到这里,它并不想听上去那么奇怪。下面的例子展示了我们如何得到一个列表的长度:-module(tut4).-export(list_length/1).list_length()-0;list_length(First|Rest)-1+list_length(Rest).“编译文件 tut4.erl”并且运行一下:29 c(tut4).ok,tut430 tut4:list_length(1,2,3,4,5,6,7).7

19、 解释下面的语句:list_length()-0;表明了空列表的长度被我们定义为0。list_length(First|Rest)-1+list_length(Rest).上面的代码表明一个非空列表的长度是第一个元素 First 加上后面剩下的 Rest 部分的长度的和。(对于高级一点的读者:这里并非只能使用递归的方式,也有一些更好的方式来实现哈。)“一般情况下我们可以在我们在其他语言中使用 记录records”“或者 结构 structs”的地方说我们使用了列 表,特别是我们试图表现一些可变大小的数据时。(就如同我们在其他语言中使用链表一样)Erlang 没有一个字符串数据类型,取而代之的是

20、使用ASCII表示的列表。所以列表97,98,99等效为字“符串 abc”。Erlang Shell 是一个聪明的系统,可以猜出我们的列表到底想要表达什么样的数据,并且以合适的方式进行输出,这在大多数场合都是适用的。例如:31 97,98,99.abc1.6 标准模块和手册页面Erlang 有很多标准模块帮助我们做一些常见的事情。例如,模块io包含了很多函数帮助我们格式化输入和输出。搜寻这些标准模块的信息,我们可以使用命令erl-man(可以是操作系统的提示符或者 Erlang Shell 的提示符都可以),下面是在操作系统的提示符下进行:%erl-man ioERLANG MODULE DE

21、FINITION io(3)MODULE io-Standard I/O Server Interface FunctionsDESCRIPTION This module provides an interface to standard Erlang IO servers.The output functions all return ok if they are suc-.如果在你的操作系统上并不支持这个特性,那么就看 Erlang/OTP 发行版本中的文档吧,或者是从www.erlang.se 网站上下载文档(html 或者pdf 格式的)或者是www.erlang.org 上面也有。

22、下面是R98 的文档地址:http:/www.erlang.org/doc/r9b/doc/index.html 1.7 输出到终端在下面的例子中我们可以很好的将格式化的结果输出到终端,我们将从中学习如何使用 io:format 函数。当然,和其他很多函数一样,我们可以在shell 中测试这些函数的实际效果:32 io:format(hello worldn,).hello worldok33 io:format(this outputs one Erlang term:wn,hello).this outputs one Erlang term:hellook34 io:format(thi

23、s outputs two Erlang terms:wwn,hello,world).this outputs two Erlang terms:helloworldok35 io:format(this outputs two Erlang terms:w wn,hello,world).this outputs two Erlang terms:hello worldok 函数format/2(一个函数format 带有两个参数)需要两个列表作为输入。这第一个列表总是在 之间的。这个列表是输出的基准串,除了里面的w 将被替换为后面的第二个列表中对应位置的内容。每个n将被替换为一个回车(或

24、者理解为替换为新的一行)。io:fomrat/2 函数如果运行一切正常的话,自己返回一个常量ok。如同其他Erlang 中的函数一样,如果发生什么错误将会直接提示出错信息。这并不是Erlang 的错误或者缺陷,只是一个经过深思熟虑的策略。Erlang 有一个经过长期检验的实现机制来捕获错误,我们稍后会深入的讨论相关的内容。作为一个联系,我们尝试让io:format 挂掉,这应该不难,在这个过程中Erlnag 本身是不会挂掉的。1.8 一个大一些的例子现在有一个大一些的例子帮助我们更加深入的学习。这里我们准备了一个从一组城市中读取气温的列表。其中一些是摄氏度,另一些是华氏度的表示,让我们以更加适

25、于阅读的方式输出这些信息:%This module is in file tut5.erl-module(tut5).-export(format_temps/1).%Only this function is exportedformat_temps()-%No output for an empty list ok;format_temps(City|Rest)-print_temp(convert_to_celsius(City),format_temps(Rest).convert_to_celsius(Name,c,Temp)-%No conversion needed Name,c

26、,Temp;convert_to_celsius(Name,f,Temp)-%Do the conversion Name,c,(Temp-32)*5/9.print_temp(Name,c,Temp)-io:format(-15w w cn,Name,Temp).36 c(tut5).ok,tut537 tut5:format_temps(moscow,c,-10,cape_town,f,70,stockholm,c,-4,paris,f,28,london,f,36).moscow -10 ccape_town 21.1111 cstockholm -4 cparis -2.22222 c

27、london 2.22222 cok 在我们关注程序怎样运行之前,注意我们在代码中添加了一些注释信息。注释都是以%开头的。注意-export(format_temps/1).这行意味着包含一个函数 format_temps/1,其他函数都是本地函数,也就是说在模块tut5 之外是看不到这些函数的。同样注意我们在shell 中运行这个程序的情况,我们的输入跨越了两行,因为太长了,这也是允许的。当调用首次format_temps 的时候,City 获得值moscow,c,-10,并且 Rest 保存着剩余的列表。然后我们调用函数print_temp(covert_to_celsius(moscow

28、,c,-10)。convert_to_celsius(moscow,c,-10)是作为 print_temps 的参数。这个嵌套的函数的执行是从内到外的一个过程。首先我们执行convert_to_celsius(moscow,c,-10),因为我们传入的参数已经是使用摄氏度的表达形式了,所以下面我们马上紧接着执行 print_temp(moscow,c,-10)。函数convert_to_celsius 的工作情况与前面的例子convert_length 很类似。print_temp 函数简单的调用了 io:format 函数。这里的-15w 表达的意思是打印传入的值,但是限定长度(或者说是数

29、据宽度)必须小于15,数据左对齐。现在我们调用format_temps(Rest),将剩余的部分作为参数传入。这个工作的方式很类似于其他语言中“”的循环结构。(这里是一个递归的过程,不用太 害怕 哈)。同样的,format_temps 函数被再次调用,这次City 得到值cape_town,f,70,我们重复上面说过的过程进行数据的处理。我们持续的运行该程序,直到列表为空。当列表为空时,执行第一个子句 format_temps(),程序简单的返回一个常量ok,至此,程序顺利结束。1.9 变量的匹配、限定和作用域我们可能需要寻找在列表中的最高和最低温度。在我们动手扩展我们前面的程序之前,让我们来

30、看一个在列表中寻找最大值的元素的函数:-module(tut6).-export(list_max/1).list_max(Head|Rest)-list_max(Rest,Head).list_max(,Res)-Res;list_max(Head|Rest,Result_so_far)when Head Result_so_far-list_max(Rest,Head);list_max(Head|Rest,Result_so_far)-list_max(Rest,Result_so_far).39 c(tut6).ok,tut640 tut6:list_max(1,2,3,4,5,7,4

31、,3,2,1).7 首先注意到这里有两个相同名称的函数list_max。尽管这些函数有不同数量的参数。在Erlang 中它们被处理为完全不同的函数。但我们需要根据name/arity 来分辨不同的函数,name 是函数的名称,arity是参数的个数,对于上面的例子分别是list_max/1 和 list_max/2。上面的例子接受一个我们构造的列表,我们使用 Result_so_far“”搬移 一个列表中的值。list_max/1 简单的假设列表中最大值是列表的头部元素,并给调用 list_max/2 来处理剩下的元素来与头部元素进行对比,在上面代码就将是list_max(2,3,4,5,7,

32、4,3,2,1,1)。如果我们尝试使用 list_max/1 来处理一个空列表,我们将得到一个错误提示。注意这个Erlang 体系不能够捕获这种类型的函数错误,但是会有其他的办法 来处理,稍后会有详细的讨论。在list_max/2“”中我们继续 走完 声誉的列表,当HeadResult_so_far 条件满足的时候使用Result_so_far 替代原先的 Head 的值。-前面的 when 是一个关键词,告诉我们如果条件为真则执行函数的这一部分,我们将这种测试过程称为界定(guard)。如果一个条件界定不为真(也就是说界定失败),我们尝试运行函数的另一部分。在这个例子中如果 Head 不是大

33、于 Result_so_far,也就是 Head等于或者小于Resutl_so_far,所以我们就不需要在函数的另一部分再加入一个界定来判断执行条件了。“一些有用的界定符例如”“大于,=”“等于,=”“不小于,=”“不大于,/=”不等于。改变上面的程序,使其变为寻找列表中最小值的函数,我们只需要将符号就可以了。(除此之外似乎还应该将函数名称改为list_min 更为恰当:))记得我曾经在较早前提起过变量只能在作用域内被赋值一次吗?在上面我们看到,Result_so_far 被重复的赋值了很多次,这是合法的,因为每次我们调用 list_max/2 的时候系统都会新建一个作用域并且每 个作用域内的

34、变量都是完全不一样的。另一种创建和赋值给变量的方法是使用操作符=。所以如果我写下M=5,一个叫做 M的变量就会被创建然后被赋值为5.如果我又在同一个作用域中写 M=6,我们将得到一个错误提示。在 shell 中尝试下面的代码:41 M=5.542 M=6.*exited:badmatch,6,erl_eval,expr,3*43 M=M+1.*exited:badmatch,6,erl_eval,expr,3*44 N=M+1.6 匹配操作符在分离和创建新的变量方面有独特的作用:45 X,Y=paris,f,28.paris,f,2846 X.paris47 Y.f,28 这里我们的X 得到了

35、值 pairs,Y得到了f,28。当然,如果我们尝试对其他的城市重复上面的操作又不改变变量,那么会得到出错信息:49 X,Y=london,f,36.*exited:badmatch,london,f,36,erl_eval,expr,3*变量能够用来提高程序的可阅读性,例如,上面的 list_max/2 函数,我们可以写:list_max(Head|Rest,Result_so_far)when Head Result_so_far-New_result_far=Head,list_max(Rest,New_result_far);这样的写法可能更加清晰一点。1.10 进一步讨论列表“记得|

36、”操作符在获取列表头部的作用吗?50 M1|T1=paris,london,rome.paris,london,rome51 M1.paris52 T1.london,rome “|”操作符也可以用来为列表增加一个头元素:53 L1=madrid|T1.madrid,london,rome54 L1.madrid,london,rome 下面我们尝试将列表进行翻转操作:-module(tut8).-export(reverse/1).reverse(List)-reverse(List,).reverse(Head|Rest,Reversed_List)-reverse(Rest,Head|R

37、eversed_List);reverse(,Reversed_List)-Reversed_List.56 c(tut8).ok,tut857 tut8:reverse(1,2,3).3,2,1 考虑Reversed_List 是如何被构造出来的。首先是从一个空列表开始,我们首先获取现有列表的头元素,放入Reversed_List 中,具体过程显示如下:reverse(1|2,3,)=reverse(2,3,1|)reverse(2|3,1)=reverse(3,2|1)reverse(3|,2,1)=reverse(,3|2,1)reverse(,3,2,1)=3,2,1 模块lists

38、包含了很多对列表进行操作的函数,例如翻转列表,在我们自己动手写一个函数之前,最好还 是首先检查一下有没有在模块中已经为我们准备好的函数。现在我们会过头来看看城市和温度的问题,但是这次将更加结构化一点。首先让我们把整个列表转化为摄氏度表示,并且测试下面的函数:-module(tut7).-export(format_temps/1).format_temps(List_of_cities)-convert_list_to_c(List_of_cities).convert_list_to_c(Name,f,F|Rest)-Converted_City=Name,c,(F-32)*5/9,Conv

39、erted_City|convert_list_to_c(Rest);convert_list_to_c(City|Rest)-City|convert_list_to_c(Rest);convert_list_to_c()-.58 c(tut7).ok,tut7.59 tut7:format_temps(moscow,c,-10,cape_town,f,70,stockholm,c,-4,paris,f,28,london,f,36).moscow,c,-10,cape_town,c,21.1111,stockholm,c,-4,paris,c,-2.22222,london,c,2.222

40、22 我们一点一点的看:format_temps(List_of_cities)-convert_list_to_c(List_of_cities).这里我们看到format_temps/1 调用了 convert_list_to_c/1。convert_list_to_c/1 获得列表List_of_cities“的头元素,如果需要的话就进行摄氏度的转换。|”操作符被用来添加转化后的元素到已转化的列表部分。Converted_City|convert_list_to_c(Rest);或者City|convert_list_to_c(Rest);我们继续这样的操作直到获取了列表中的最后一个元素

41、(也就是到列表为空)convert_list_to_c()-.现在我们就完成了对列表的转换工作,我们添加一个函数并且输出它:-module(tut7).-export(format_temps/1).format_temps(List_of_cities)-Converted_List=convert_list_to_c(List_of_cities),print_temp(Converted_List).convert_list_to_c(Name,f,F|Rest)-Converted_City=Name,c,(F-32)*5/9,Converted_City|convert_list_t

42、o_c(Rest);convert_list_to_c(City|Rest)-City|convert_list_to_c(Rest);convert_list_to_c()-.print_temp(Name,c,Temp|Rest)-io:format(-15w w cn,Name,Temp),print_temp(Rest);print_temp()-ok.60 c(tut7).ok,tut761 tut7:format_temps(moscow,c,-10,cape_town,f,70,stockholm,c,-4,paris,f,28,london,f,36).moscow -10 c

43、cape_town 21.1111 cstockholm -4 cparis -2.22222 clondon 2.22222 cok 我们现在已经添加了一个函数去寻找有最高气温和最低气温的城市了。这个程序并不是最有效率的,我们4 次遍历整个列表,但是对于清晰程度和正确性来说却没有太大的影响,我们只在确实需要优化性能的时候进行优化:-module(tut7).-export(format_temps/1).format_temps(List_of_cities)-Converted_List=convert_list_to_c(List_of_cities),print_temp(Conver

44、ted_List),Max_city,Min_city=find_max_and_min(Converted_List),print_max_and_min(Max_city,Min_city).convert_list_to_c(Name,f,Temp|Rest)-Converted_City=Name,c,(Temp-32)*5/9,Converted_City|convert_list_to_c(Rest);convert_list_to_c(City|Rest)-City|convert_list_to_c(Rest);convert_list_to_c()-.print_temp(N

45、ame,c,Temp|Rest)-io:format(-15w w cn,Name,Temp),print_temp(Rest);print_temp()-ok.find_max_and_min(City|Rest)-find_max_and_min(Rest,City,City).find_max_and_min(Name,c,Temp|Rest,Max_Name,c,Max_Temp,Min_Name,c,Min_Temp)-if Temp Max_Temp-Max_City=Name,c,Temp;%Change true-Max_City=Max_Name,c,Max_Temp%Unc

46、hanged end,if Temp Min_City=Name,c,Temp;%Change true-Min_City=Min_Name,c,Min_Temp%Unchanged end,find_max_and_min(Rest,Max_City,Min_City);find_max_and_min(,Max_City,Min_City)-Max_City,Min_City.print_max_and_min(Max_name,c,Max_temp,Min_name,c,Min_temp)-io:format(Max temperature was w c in wn,Max_temp,

47、Max_name),io:format(Min temperature was w c in wn,Min_temp,Min_name).62 c(tut7).ok,tut763 tut7:format_temps(moscow,c,-10,cape_town,f,70,stockholm,c,-4,paris,f,28,london,f,36).moscow -10 ccape_town 21.1111 cstockholm -4 cparis -2.22222 clondon 2.22222 cMax temperature was 21.1111 c in cape_townMin te

48、mperature was-10 c in moscowok1.11 If 和 Case 语句函数find_max_and_min 将为我们找到最高和最低气温。我们在这里引入了一个新的关键字if,它的工作情况如下:if Condition 1-Action 1;Condition 2-Action 2;Condition 3-Action 3;Condition 4-Action 4end 注意,在end“前面的最后一个条件是没有;”的!这里的判定条件和界定(Guard)是一样的,测试条件的真或假。Erlang 从最高处开始执行,直到它找到一个为真的条件,并执行其内部的代码,并且很重要的是它将

49、忽略其他剩下的条件,不论其他剩下的条件中是否还有为真的情况。一个条件当是常量的时候意味着永远为真,true 和常量(atoms)常常用来作为 if 的最后一个条件。作为当其他所有条件都为假时 的执行出口。下面是一个简短的程序,用来表现if 工作的情况:-module(tut9).-export(test_if/2).test_if(A,B)-if A=5-io:format(A=5n,),a_equals_5;B=6-io:format(B=6n,),b_equals_6;A=2,B=3-%i.e.A equals 2 and B equals 3 io:format(A=2,B=3n,),a

50、_equals_2_b_equals_3;A=1;B=7-%i.e.A equals 1 or B equals 7 io:format(A=1;B=7n,),a_equals_1_or_b_equals_7 end.下面是对程序的测试:64 c(tut9).ok,tut965 tut9:test_if(5,33).A=5a_equals_566 tut9:test_if(33,6).B=6b_equals_667 tut9:test_if(2,3).A=2,B=3a_equals_2_b_equals_368 tut9:test_if(1,33).A=1;B=7a_equals_1_or_b

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 技术资料 > 其他杂项

本站为文档C TO C交易模式,本站只提供存储空间、用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。本站仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知得利文库网,我们立即给予删除!客服QQ:136780468 微信:18945177775 电话:18904686070

工信部备案号:黑ICP备15003705号-8 |  经营许可证:黑B2-20190332号 |   黑公网安备:91230400333293403D

© 2020-2023 www.deliwenku.com 得利文库. All Rights Reserved 黑龙江转换宝科技有限公司 

黑龙江省互联网违法和不良信息举报
举报电话:0468-3380021 邮箱:hgswwxb@163.com