Erlang学习笔记四

二进制型

即以大小号和255位内数字组成的数据流,可以把任何内置数据压缩为bit,也可以再解压出来。此外假如二进制型能用文字显示则会显示文字.此外二进制型的位数是8的倍数,否则就是位串类型

<<5,6,8>>
<<"abc">>

 

压缩io列表

对于元素是255内数字组成的列表,可以通过函数将其压缩成一维的二进制数据

test()->
    list_to_binary([<<5,3>>,5,6,<<7>>]).
//<<5,3,5,6,7>>

 

切割二进制

test()->
    split_binary(<<5,6,7,8,9,12>>,3).
//{<<5,6,7>>,<<"\b\t\f">>}

 

对数据进行编码解码

test()->
    Student = {tang,55},
    Key=term_to_binary(Student),
    //<<131,104,2,100,0,4,116,97,110,103,97,55>>
    byte_size(Key),//12
    binary_to_term(Key).//{tang,55}

 

使用位语法打包及拆包RGB颜色

test()->
    R = 2,
    G = 61,
    B = 22,
    RGB = <<R:5,G:6,B:5>>,//<<23,182>>
    <<R2:5,G2:6,B2:5>>=RGB,
    R2,//2
    G2,//61
    B2.//22

 

位运算的后缀表达式

有四种表达式:

<<Value>>
<<Value:Size>>
<<Value/TypeSpecifierList>>
<<Value:Size/TypeSpecifierList>>

位运算允许在前面临时获得的Size在后面直接拿来声明长度。

<<Size:4,Data:Size/binary>> = Ceshi

 

位运算的类型指定列表

采用End-Sign-Type-Unit的格式,其中任意项都可以被省略,会使用默认值

End是字节顺序有big、little、native,默认big。big为高位优先、little则是低位优先,native是按照机器的顺序。最好的办法是用term_to_binary和binary_to_term来进行转码。

Sign是模式匹配,有singned、unsigned,默认unsigned。

Type是数据类型,有integer、float、binary、bytes、bitstring、bits、utf8、utf16、utf32,默认为integer

Unit写法为unit:1|2|..256,integer、float、bitstring的默认值为1,binary是8,而utf系列没有unit。字段长度为unit长度乘以Size。

 

匹配消息头

is_head(<<2#11111111111:11,B:2,C:2>>)->
    case B of
        0 -> {2,5};
        1 -> exit(badVsn);
        2 -> 2;
        3 -> 1
    end,
    case C of
        0 -> exit(badLayer);
        1 -> 3;
        2 -> 2;
        3 -> 1
    end.

通过2进则的十一个1来匹配消息头,就能很清楚的找到其是不是正确的头部,假如匹配失败则可以在调用的时候用try来处理不是时候的操作

ps:用file:read_file可以读取文件为二进制型

 

位推导

和列表推导类似,但是是针对位的操作,可以生成列表或者二进制型

test()->
    Key = <<16#5d>>,
    [ X || <<X:1>> <= Key],//[0,1,0,1,1,1,0,1]
    << <<X>> || <<X:1>> <= Key>>.//<<0,1,0,1,1,1,0,1>>

 

动态函数调用

类似java的反射调用,但是要尽量避免这种调用方式,因为这会导致一些分析程序无法发现问题

test()->
    apply(bit,add,[5,15]).//20

add(A,B)->
    A+B.

 

算数表达式

+X //正x
-X //负X
X + Y //加法
X - Y //减法
X * Y //乘法
X / Y //浮点除法
bnot X //对X执行按位取反
X div Y //X被Y整除
X rem Y //X被Y整除后余数
X band Y //X和Y按位与
X bor Y //X和Y按位或
X bxor Y //X和Y按位异或
X bsl N //把X向左算数位移N位
X bsr N //把X向右算数位移N位

 

模块属性

-module(name). 

模块声明,必须是文件第一个属性,并且要确保name是文件的文件名

 

-import(Mod,[Name/Arity,...])

声明要从mod模块中导入参数为Arity个的name方法

 

-export([Name/Arity,...])

声明希望导出的函数

 

-compile(Options).

添加一个配置选择到编译器的选择列表中,可以是单个编译器选择也可以是选择列表

ps:-compile(export_all)是导出全部函数,这样就不用显式调用-export来一个个导出了

 

-vsn(Version).

声明模块版本号,可以是任何值,主要作为分析程序或说明文档作用。

 

自定义属性及获取

-module(bit).
-vsn(adw).
-ceshi(aa).
-export([test/0]).

test()->
    Key = bit:module_info(attributes),
    Key.

不传参则全部返回,用beam_lib:chunks("bit.beam",[attributes]).也可以达到同样效果,并且不需要编译器事先载入对应的beam

 

块表达式

当需要多行表达式但是目标位置只有一行表达式容量时候

test()->
    [
        begin
        Y=X rem 2-1,
        Y*2
        end
        ||X<-[1,2,3,4,5] //[0,-2,0,-2,0]
    ].

 

函数返回布尔值规范

如果有可能返回两个原子来表达状态,最好用返回true和false来表示。而假如想用布尔值返回,则名字最好写成is_XXX之类的,让人一眼就能看出来这里要返回是或否。使用true和false还有一个好处就是可以充分利用标准函数库,而不需要中转站来分析原子含义。

 

布尔表达式

not A //逻辑非
A and B //逻辑与
A or B //逻辑或
A xor B //逻辑异或

 

注释

%是注释符号

 

动态调用函数

start(Tag) ->
    spawn(fun() -> loop(Tag) end).

loop(Tag) ->
    sleep(),
    Val = b:x(),
    io:format("~ts~n",[Val]),
    loop(Tag).

sleep() ->
    receive
        after 3000 -> true
    end.

假如你的函数依赖外部函数的话,当你更新的外部函数的team的时候,函数会自动去调用现在存在的那个新的外部函数,不需要额外操作,通过这样可以实现热更新。此外要注意的是erlang最多允许两个版本在允许,即旧版和当前版本。假如出现新版本替换,则原来的旧版程序都会被掐灭,而当前版变旧版,新版变当前版。

 

转义字符

\b //退格符
\d //删除符
\e //换码符
\f //换页符
\n //换行符
\r //回车符
\s //空格符
\t //制表符
\v //垂直制表符
\x{...} //十六进制符
\^a..\^z //Ctrl+A到Z
\' //单引号
\" //双引号
\\ //反斜杠
\C //C字符的ASCII编码

 

表达式和表达式序列

表达式必然有一个返回值,所以记录声明和模块属性没返回值不是表达式。表达式序列则指以逗号分割最后以句号结尾的一系列表达式。要注意的是这种表达式只会返回最后一个的值,但是可以使用序列前面绑定的值。

 

函数引用

有时候我们会希望把函数当参数引用,这时候就要用函数引用

X = fun test/1. //引用本地函数
Y = fun mod:test/1. //引用外部函数

 

包含文件

-module(he).
-include("./he.hrl").
-export([test/0]).

test()->
    #student{name = feng}.

使用hrl文件就可以多个erl文件共享配置,此外还有include_lib,似乎是用来获得包含库的头文件

 

++与--

A++B 使A和B相加或拼接

A--B 从列表A中移除列表B,假如B中k出现N次则A中只会移除N次

 

 

 

上一篇:Windows Server 2016-启用默认Windows搜索服务


下一篇:rabbitmq和erlang的安装和搭建