基本数据类型
整数
- 没有最大值,可以是任意值,(可用内存大小是实际最大值限制)
- 大整数自动转换成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