erlang-基本语法_5、记录(record)、guard、高阶函数 (Fun)变量作用域、匿名变量

写在前面

本文主要是以一个erlang的学习记录,有错误的地方欢迎指正。

Snip20180615_24.png

记录 record

记录其实就是元组的另一种形式。通过使用记录,可以给元组里的各个元素关联一个名称。

何时使用记录

当你可以用一些预先确定且数量固定的原子来表示数据时;
当记录里的元素数量和元素名称不会随时间而改变时;
当存储空间是个问题时,典型的案例是你有一大堆元组,并且每个元组都有相同的结构

新建一个文件 record.erl,代码如下:

-module(record).
% 定义一个记录
-record(book,{author, bookname, chapters = 0}).
% 编译文件
1> c(record).
{ok,record}
2>      
%在Erlang的shell中,如果想创建record的实例,必须先读取记录的定义,使用命令rr(read record)             
3> rr("record.erl").
[book]

% 创建记录
4> Shuihu = #book{author ="edit", bookname= "haliboke"}.
#book{author = "edit",bookname = "haliboke",chapters = 0}

% 更新记录
6> Shuihu2 = Shuihu#book{chapters = 36}.
#book{author = "edit",bookname = "haliboke",chapters = 36}

% 提取记录.  
7> #book{author = Author1 , bookname= Bookname,chapters = Pirse} = Shuihu.
#book{author = "edit",bookname = "haliboke",chapters = 0}
8> Author1.
"edit"
9> Bookname.
"haliboke"
10> pirse.
pirse
11> Pirse.
0
12> 

Erlang匹配、Guards与变量的作用域

示例:在列表中找出最大的值,新建一个tut6.erl文件如下:

-module(tut6).

-export([list_max/1]).

list_max([Head|Rest]) ->
    list_max(Rest,Head).

list_max([], Res) ->
    Res;

%when 用在函数的 -> 前时是一个特别的的单词,
%它表示只有测试条件为真时才会用到函数的这一部分。
%这种类型的测试被称这为 guard 如果 guard 为假 (即 guard 测试失败),
%则跳过此部分而尝试使用函数的后面一部

list_max([Head|Rest],Result_so_far) when Head > Result_so_far ->
    list_max(Rest,Head);
    
%每个变量在其作用域内只能被赋值一次。
%从上面的例子中也可以看到,Result_so_far 却被赋值多次。
%这是因为,每次调用一次 list_max/2 函数都会创建一个新的作用域。
%在每个不同的作用域中,Result_so_far 都被当作完全不同的变量。

list_max([_Head|Rest],Result_so_far) ->
    list_max(Rest,Result_so_far).
%编译
3> c(tut6).
{ok,tut6}
%调用方法,找出列表中最大的值
4> tut6:list_max([1,2,3,4,5,33,4,5,6,7,8]). 
33
5> 

guard

when 用在函数的 -> 前时是一个特别的的单词,
它表示只有测试条件为真时才会用到函数的这一部分。
这种类型的测试被称这为 guard

guard 中的操作符还包括:

<小于
> 大于
== 等于
>= 大于或等于
=< 小于或等于
/= 不等于

作用域

每个变量在其作用域内只能被赋值一次。
从上面的例子中也可以看到,Result_so_far 却被赋值多次。
这是因为,每次调用一次 list_max/2 函数都会创建一个新的作用域。
在每个不同的作用域中,Result_so_far 都被当作完全不同的变量。

匹配操作符

5> {X,Y} = {paris,{f,28}}.
{paris,{f,28}}
6> X.
paris
7> Y.
{f,28}
8> 

高阶函数 (Fun)

在shell中定义了一个数值翻倍的函数

1> Xf = fun (X) -> X * 2 end.
#Fun<erl_eval.6.52032458>
2> Xf(5).
10
3> 

操作列表处理函数 foreach 、 map

foreach(Fun,[First|Rest]).
    Fun(First),
    foreach(Fun,Rest);
foreach(Fun,[])->
    ok.
map(Fun, [First|Rest]) ->
    [Fun(First)|map(Fun,Rest)];
map(Fun,[])->
    [].

在 shell 中使用 map 的 Xf 函数生成一个新的列表:

1> Xf = fun (X) -> X * 2 end.
#Fun<erl_eval.6.52032458>
2> Xf(5).
10
3> 
3> 
3> lists:map(Xf,[1,2,3,4]).
[2,4,6,8]
4> 

输出一组城市的温度值

4> Print_City = fun({City,{X,Temp}}) -> io:format("~-15w ~w ~w~n",[City, X, Temp]) end.
#Fun<erl_eval.6.52032458>
6> lists:foreach(Print_City,[{moscow,{c, -10}},{cape_town, {f, 70}},{stockholm, {c, -4}},{paris,{f, 28}},{londom,{f,36}}]).
moscow          c -10
cape_town       f 70
stockholm       c -4
paris           f 28
londom          f 36
ok
7> 

遍历城市温度列表并将每个温度值都转换为摄氏温度表示

-module(tut13).
-export([convert_list_to_c/1]).

convert_to_c({Name,{f, Temp}}) ->
    {Name, {c, trunc((Temp - 32 ) * 5 / 9)}};

convert_to_c({Name, {c, Temp}}) ->
    {Name, {c, Temp}}.

convert_list_to_c(List) ->
    lists:map(fun convert_to_c/1,List).
%编译
8> c(tut13).
{ok,tut13}
9> 
9> tut13:convert_list_to_c([{moscow,{c,-10}}]).
[{moscow,{c,-10}}]
11> 
11> tut13:convert_list_to_c([{moscow, {c, -10}}, {cape_town, {f, 70}},
11> {stockholm, {c, -4}}, {paris, {f, 28}}, {london, {f, 36}}]).
[{moscow,{c,-10}},
 {cape_town,{c,21}},
 {stockholm,{c,-4}},
 {paris,{c,-2}},
 {london,{c,2}}]

匿名变量

fun({_,{c,Temp1}},{_,{c, Temp2}})-> Temp1 < Temp2 end.

这儿用到了匿名变量 "_" 的概念。匿名变量常用于忽略一个获得的变量值的场景下。
当然,它也可以用到其它的场景中,而不仅仅是在高阶函数这儿。
Temp1 < Temp2 说明如果 Temp1 比 Temp2 小,则返回 true。

引用网络博客内容:
https://www.w3cschool.cn/erlang/tohb1p5z.html (w3cschool erlang教程)

个人博客地址:https://zhangyongfeng1.github.io/
简书地址://www.greatytc.com/u/137f325832fb

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,776评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,527评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,361评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,430评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,511评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,544评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,561评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,315评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,763评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,070评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,235评论 1 343
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,911评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,554评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,173评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,424评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,106评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,103评论 2 352

推荐阅读更多精彩内容