美文网首页
erlang-基本语法_5、记录(record)、guard、高

erlang-基本语法_5、记录(record)、guard、高

作者: zhang_yongfeng | 来源:发表于2018-06-15 16:21 被阅读0次

    写在前面

    本文主要是以一个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/
    简书地址:https://www.jianshu.com/u/137f325832fb

    相关文章

      网友评论

          本文标题:erlang-基本语法_5、记录(record)、guard、高

          本文链接:https://www.haomeiwen.com/subject/wyemeftx.html