基本数据类型

整数

  • 没有最大值,可以是任意值,(可用内存大小是实际最大值限制)
  • 大整数自动转换成bignums类型,比固定大小的整数类型相对效率较低
  • Base#Value 可表示基数不是10的整数

      比如 2#1010 (二进制)   -16#EA (16进制)
    
  • #Character 表示ASCII值 (即为字符

      比如 $a  $\n
    

浮点数

两种表示形式,如下两个值是一样的

* 1323.233
* 132323.3E-2

数学运算符

类型 描述 数据类型 优先级
+ 一元操作符+ 整数/浮点数 V0
- 一元操作符- 整数/浮点数 V0
* 乘法 整数/浮点数 V1
/ 除法 整数/浮点数 V1
div 整数除法 整数 V1
rem 整数取余 整数 V1
+ 加法 整数/浮点数 V2
- 减法 整数/浮点数 V2

基元

基元(atom)表示文字常量。(作用类似枚举类型),基元有以下两种声明方式

  • [email protected]
    小写字母开头,后面可以使用 字母 / 数字 / @ / . / __
  • 'Any #4\n'
    单引号封装起来则可以使用任意字符

基元是按照字典顺序来排序的

布尔类型

Erlang没有真正的布尔类型。基元true和false与布尔操作符一起使用,但并不是布尔类型。

逻辑运算符

运算 描述
and 逻辑与
andalso 逻辑与快捷形式
or 逻辑或
orelse 逻辑或快捷形式
xor 异或:两个参数一真一假,返回真
not 取反

元组

元组使用 {...} 来定义,元素用逗号隔开,如 { 123,bcd} {} {abc,{133,313}}

当一个元组第一个元素是基元是,我们称它为标记(tag)。这是Erlang惯例来表示不同类型数据,通常表示程序中的特殊意义。

元组的索引是从 1 开始

列表

列表(List)使用 [...] 来定义,元素用逗号隔开,如 [1233,ad] [] ['dad',adf] "Hello" [$H,$e,$l,$l,$o]

列表的结构为 [头部 | 尾部] , List的递归定义: List = [Element|List] or []

如果分解后的列表最后一个尾部项是一个空列表,那么这是一个正确的列表或结构良好的列表。

列表操作:分解[Head|Tail],列表相加++ ,列表相减--.

在一个列表前加一个元素,有两种方法:

  • 直接使用构造器,如:[1|[2,3,4]]
  • 使用++运算,如:[1]++[2,3,4] (效率低于构造器)

列表解析

格式: NewList = [Expression || GeneratorExp1, GeneratorExp2, ..., GeneratorExpN, Condition1, Condition2, ... ConditionM]

如,X取值为1或5,Y取值为6或7,我们要找到和能被3整除的X和Y:

[{X,Y}||X<-[1,5],Y<-[6,7],(X+Y) rem 3 =:=0].

字符和字符串

字符就是整数

字符串是整数的列表

由双引号和字符串来表示,其实质是List。如"hello"等价于[$h,$e,$l,$l,$o].

两个相邻的字符串将组合成一个字符串,即"he" "llo"等价于"hello"。

也可以用Binary来表示字符串。

基元与字符串

  • 操作不同:基元只能进行比较操作,字符串进行列表操作。
  • 效率不同:
    • 空间:字符串所占空间与字符串大小成正比。基元在系统表中表示,仅需要几个字节做索引,与它的大小无关。
    • 时间:字符串比较,系统要遍历他们比较字符串的每个字符。基元比较只需比较它们的内部标识符。
  • 可使用字符串表示一个基元,即把字符串当作一个常量。

比较运算符

运算 描述
== 等于
/= 不等于
=:= 精确等于 (比较值与数据类型)
=/= 精确不等于 (比较值与数据类型)
=< 小于或等于
< 小于
>= 大于或等于
> 大于

比较不同数据类型,可参考下面的等级排序

number < atom < reference < fun < port < pid < tuple < list < binary

变量

变量必须以大写字母开头,后面可跟 大小写字母 / 整数 / 下划线

单次赋值

变量可以被遮盖

所有变量都是局部的,不存在全局变量。

变量不需要声明,只需要使用。(Erlang具有动态类型系统。)

Erlang所有函数变量调用都是按值调用:函数被求值之前,所有函数调用参数都已经被求值。

Bit Strings and Binaries

Bit Strings代表无类型的内存区域,表现形式为<<E1,...,En>>

每一个Ei都是bit string的一部分。 每一个Ei都是一个值,后面可跟可选的size和type specifier list。

Ei = Value |
     Value:Size |
     Value/TypeSpecifierList |
     Value:Size/TypeSpecifierList
  • Value
    • 对于 bit string 构造器, value 是一个可以计算出integer,float , bit string的表达式
    • 对于bit string 匹配, value必须是变量,integer,float , string

<<"abc">> 是后者<<$a,$b,$c>>的语法糖表现形式)

  • Size

    • 对于 bit string 构造器, value 是一个可以计算出integer的表达式
    • 对于bit string 匹配, value必须是integer型变量,integer
    • For integer it is 8.
    • For float it is 64.
    • For binary and bitstring it is the whole binary or bit string
    • For the utf8, utf16, and utf32 types, Size must not be given。size 会被隐式推导。
    • For utf8, Value is encoded in 1-4 bytes.
    • For utf16, Value is encoded in 2 or 4 bytes.
    • For utf32, Value is always be encoded in 4 bytes.
  • TypeSpecifierList

    • list
    • (-) 作为连接符
  • Type

    • integer | float | binary | bytes | bitstring | bits | utf8 | utf16 | utf32
    • The default is integer. bytes is a shorthand for binary and bits is a shorthand for bitstring. See below for more information about the utf types.
  • Signedness

    • signed | unsigned
    • Only matters for matching and when the type is integer. The default is unsigned.
  • Endianness

    • big | little | native
    • Endianness only matters when the Type is either integer, utf16, utf32, or float. The default is big.
  • Unit

    • unit:IntegerLiteral
    • The allowed range is 1..256. Defaults to 1 for integer, float, and bitstring, and to 8 for binary. No unit specifier must be given for the types utf8, utf16, and utf32.

Examples:

1> Bin1 = <<1,17,42>>.
<<1,17,42>>
2> Bin2 = <<"abc">>.
<<97,98,99>>
3> Bin3 = <<1,17,42:16>>.
<<1,17,0,42>>
4> <<A,B,C:16>> = <<1,17,42:16>>.
<<1,17,0,42>>
5> C.
42
6> <<D:16,E,F>> = <<1,17,42:16>>.
<<1,17,0,42>>
7> D.
273
8> F.
42
9> <<G,H/binary>> = <<1,17,42:16>>.
<<1,17,0,42>>
10> H.
<<17,0,42>>
11> <<G,H/bitstring>> = <<1,17,42:12>>.
<<1,17,1,10:4>>
12> H.
<<17,1,10:4>>
13> <<1024/utf8>>.
<<208,128>>

可以用模式匹配的方式轻松的获取内存区域中某一位置的值,用Erlang来处理数据很方便,但是不推荐使用Erlang来处理大量的数据,因为Erlang在数据处理方面比C++慢。

当Bit Strings中所有的Ei的Size都为8时,叫做Binaries。

Binaries也支持查询式的操作,实际上Binaries能查询得到List,List也能查询得到Binary。最直观的还是举例来看一下。

  • List to List

    [2*N || N <- [1,2,3,4]].
    [2,4,6,8]
    
  • List to Binary,注意要写明类型或size。

    <<<<(N*2):8>> || N <- [1,2,3,4]>>.
    <<2,4,6,8>>
    
  • Binary to List,注意<-变成了<=

    [2*N || <<N>> <= <<1,2,3,4>>].
    [2,4,6,8]
    
  • Binary to Binary

    <<<<(N*2):8>> || <<N>> <= <<1,2,3,4>>>>.
    <<2,4,6,8>>
    

位运算符 (Binary)

位运算符 Description
bond 按位与
bor 按位或
bxor 按位异或
bnot 按位非
bsl 按位左移,第二个参数给出移动位数
bsr 按位右移,第二个参数给出移动位数

Reference

引用是Erlang运行时系统唯一标识的术语,可通过调用 make_ref/0 创建。

Fun

fun 是函数对象。fun可用于建立匿名函数,函数作为参数传参。

函数声明形式:

fun
    [Name](Pattern11,...,Pattern1N) [when GuardSeq1] ->
              Body1;
    ...;
    [Name](PatternK1,...,PatternKN) [when GuardSeqK] ->
              BodyK
end

[Name] 省略即为匿名函数

将一个已经定义的函数赋值给函数对象。形式如下:

fun Name/Arity
fun Module:Name/Arity
···

Arity 为参数数量


Example:

``` Erlang
1> Fun1 = fun (X) -> X+1 end.
#Fun<erl_eval.6.39074546>
2> Fun1(2).
3
3> Fun2 = fun (X) when X>=5 -> gt; (X) -> lt end.
#Fun<erl_eval.6.39074546>
4> Fun2(7).
gt
5> Fun3 = fun Fact(1) -> 1; Fact(X) when X > 1 -> X * Fact(X - 1) end.
#Fun<erl_eval.6.39074546>
6> Fun3(4).
24
7> hof1:filter(fun hof1:palin/1,[[2,2],[2,3]]).
[[2,2]]

Port Identifier

A port identifier identifies an Erlang port.

open_port/2, which is used to create ports, returns a value of this data type.

Read more about ports in Ports and Port Drivers.

Pid

进程标识符

如下BIFs用于创建进程

  • spawn/1,2,3,4
  • spawn_link/1,2,3,4
  • spawn_opt/4

Example:

1> spawn(m, f, []).
<0.51.0>

In the following example, the BIF self() returns the pid of the calling process::

-module(m).
-export([loop/0]).

loop() ->
    receive
        who_are_you ->
            io:format("I am ~p~n", [self()]),
            loop()
    end.

1> P = spawn(m, loop, []).
<0.58.0>
2> P ! who_are_you.
I am <0.58.0>
who_are_you

Map

map 是key-value的复合数据类型,形式:#{Key1=>Value1,...,KeyN=>ValueN}

some BIFs Examples:

1> M1 = #{name=>adam,age=>24,date=>{july,29}}.
#{age => 24,date => {july,29},name => adam}
2> maps:get(name,M1).
adam
3> maps:get(date,M1).
{july,29}
4> M2 = maps:update(age,25,M1).
#{age => 25,date => {july,29},name => adam}
5> map_size(M).
3
6> map_size(#{}).
0

A collection of maps processing functions can be found in maps manual page in STDLIB.

Read more about maps in Map Expressions.

Record

Record类似c的struct,但并不是真正的数据类型,Record表达式会在编译时转为tuple表达式。

定义形式

-record(Name, {Field1 [= Value1],
               ...
               FieldN [= ValueN]}).

Examples:

-module(person).
-export([new/2]).

-record(person, {name, age}).

new(Name, Age) ->
    #person{name=Name, age=Age}.

1> person:new(ernie, 44).
{person,ernie,44}

% 新建Record:
#Name{Field1=Expr1,...,FieldK=ExprK}
%其中某些Field可以省略,这时这些Field将获得默认值。

% 如果需要将多个Field赋同一值,可以用下面的方式:
#Name{Field1=Expr1,...,FieldK=ExprK, _=ExprL}
% 这时所有省略的Field都将被赋值成ExprL

% 访问Field:
Expr#Name.Field

% 更新Field
Expr#Name{Field1=Expr1,...,FieldK=ExprK}

Escape Sequences (转义字符)

Sequence Description
\b Backspace
\d Delete
\e Escape
\f Form feed
\n Newline
\r Carriage return
\s Space
\t Tab
\v Vertical tab
\XYZ, \YZ, \Z Character with octal representation XYZ, YZ or Z
\xXY Character with hexadecimal representation XY
\x{X...} Character with hexadecimal representation; X... is one or more hexadecimal characters
\^a...\^z , \^A...\^Z Control A to control Z
\' Single quote
\" Double quote
\ Backslash

Type Conversions

1> atom_to_list(hello).
"hello"
2> list_to_atom("hello").
hello
3> binary_to_list(<<"hello">>).
"hello"
4> binary_to_list(<<104,101,108,108,111>>).
"hello"
5> list_to_binary("hello").
<<104,101,108,108,111>>
6> float_to_list(7.0).
"7.00000000000000000000e+00"
7> list_to_float("7.000e+00").
7.0
8> integer_to_list(77).
"77"
9> list_to_integer("77").
77
10> tuple_to_list({a,b,c}).
[a,b,c]
11> list_to_tuple([a,b,c]).
{a,b,c}
12> term_to_binary({a,b,c}).
<<131,104,3,100,0,1,97,100,0,1,98,100,0,1,99>>
13> binary_to_term(<<131,104,3,100,0,1,97,100,0,1,98,100,0,1,99>>).
{a,b,c}
14> binary_to_integer(<<"77">>).
77
15> integer_to_binary(77).
<<"77">>
16> float_to_binary(7.0).
<<"7.00000000000000000000e+00">>
17> binary_to_float(<<"7.000e+00>>").
7.0

一些类型判断函数

is_atom/1           
is_binary/1        
is_bitstring/1      
is_boolean/1        
is_builtin/3       
is_float/1          
is_function/1       is_function/2      
is_integer/1        
is_list/1           
is_number/1        
is_pid/1            
is_port/1           
is_record/2         is_record/3         
is_reference/1      
is_tuple/1