3,。数据类型 | 3. Data Types
3种数据类型
Erlang提供了许多数据类型,在本节中列出了这些类型。
3.1项
任何数据类型的数据都称为术语
。
3.2号码
数字文字有两种类型,整数
和浮点数
。除了传统的符号外,还有两个Erlang特有的符号:
$char
字符的ASCII值或unicode代码点char
。
base
#
value
与基数base
的整数,必须是范围在2..36的整数。
例子:
1> 42.
42
2> $A.
65
3> $\n.
10
4> 2#101.
5
5> 16#1f.
31
6> 2.3.
2.3
7> 2.3e3.
2.3e3
8> 2.3e-3.
0.0023
3.3原子
一个原子是一个文字,一个有名字的常量。如果原子不是以小写字母开头,或者包含除字母数字字符,下划线(_)或@以外的其他字符,则原子将被括在单引号(')中。
例子:
hello
phone_number
'Monday'
'phone number'
3.4位字符串和二进制
位字符串用于存储非类型化内存区域。
位字符串使用bit syntax
。
由多个可以被8整除的比特组成的比特串被称为二进制文件
例子:
1> <<10,20>>.
<<10,20>>
2> <<"ABC">>.
<<"ABC">>
1> <<1:1,0:1>>.
<<2:2>>
有关更多示例,请参阅Programming Examples
。
3.5参考文献
引用是一个在调用创建的Erlang运行时系统中唯一的术语make_ref/0
。
3.6有趣之处
有趣的是功能对象。Funs使创建匿名函数成为可能,并将函数本身 - 而不是其名称 - 作为其他函数的参数。
例子:
1> Fun1 = fun (X) -> X+1 end.
#Fun<erl_eval.6.39074546>
2> Fun1(2).
3
阅读更多关于funs的内容Fun Expressions
。有关更多示例,请参阅Programming Examples
。
3.7端口标识符
端口标识符标识一个Erlang端口。
open_port/2
,用于创建端口,返回此数据类型的值。
阅读有关端口的更多信息Ports and Port Drivers
。
3.8 PID
进程标识符PID标识进程。
以下用于创建进程的BIF返回此数据类型的值:
spawn/1,2,3,4
spawn_link/1,2,3,4
spawn_opt/4
例子:
1> spawn(m, f, []).
<0.51.0>
在以下示例中,BIF self()
返回调用进程的pid:
-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
阅读有关过程的更多信息Processes
。
3.9元组
元组是一种复合数据类型,具有固定的术语数:
{Term1,...,TermN}
Term
元组中的每一项称为元素
。元素
的数量被认为是元组的大小
。
有许多BIF来操纵元组。
例子:
1> P = {adam,24,{july,29}}.
{adam,24,{july,29}}
2> element(1,P).
adam
3> element(3,P).
{july,29}
4> P2 = setelement(2,P,25).
{adam,25,{july,29}}
5> tuple_size(P).
3
6> tuple_size{}).
0
3.10地图
一个映射是一个复合数据类型,它具有可变数量的键值关联:
#{Key1=>Value1,...,KeyN=>ValueN}
映射中的每个键值关联称为关联对
。该对中的关键部分和有价值部分称为元素
。关联对
的数量被认为是地图的大小
。
有许多BIF可以操纵地图。
例子:
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
可以maps
在STDLIB的手册页中找到一组地图处理函数。
阅读更多关于地图的信息Map Expressions
。
注意
在Erlang/OTP R17期间,地图被认为是实验的。
3.11列表
列表是具有可变数量的术语的复合数据类型。
[Term1,...,TermN]
Term
列表中的每个术语都称为一个元素
。元素
的数量被认为是列表的长度
。
形式上,列表要么是空列表,[]
要么由头部
(第一个元素)和尾部
(列表的其余部分)组成。该尾巴
也是一个列表。后者可以表示为[H|T]
。[Term1,...,TermN]
上面的符号与列表相同[Term1|[...|[TermN|[]]]]
。
例子:
[]
是一个列表,因此
[c|[]]
是一个列表,因此
[b|[c|[]]]
是一个列表,因此
[a|[b|[c|[]]]]
是一个列表,或者简单地说[a,b,c]
尾部是列表的列表有时称为适当的列表
。例如,允许列出尾部不是列表的列表[a|b]
。但是,这种类型的清单几乎没有实际用处。
例子:
1> L1 = [a,2,{c,4}].
[a,2,{c,4}]
2> [H|T] = L1.
[a,2,{c,4}]
3> H.
a
4> T.
[2,{c,4}]
5> L2 = [d|T].
[d,2,{c,4}]
6> length(L1).
3
7> length([]).
0
列表处理函数的集合可以在lists
STDLIB中的手册页。
3.12字符串
字符串用双引号(“)括起来,但不是Erlang中的数据类型,而是一个字符串,它是"hello"
列表的简写形式[$h,$e,$l,$l,$o]
,也就是说[104,101,108,108,111]
。
两个相邻的字符串连接成一个。这是在编译中完成的,因此不会产生任何运行时开销。
例子:
"string" "42"
等于
"string42"
3.13记录
记录是用于存储固定数量的元素的数据结构。它命名了字段,并且与C中的结构类似。但是,记录不是真正的数据类型。相反,记录表达式在编译期间被转换为元组表达式。因此,除非采取特殊行动,否则shell不能理解记录表达式。有关详细信息,请参阅shell(3)
STDLIB中的手册页)。
例子:
-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}
详细了解记录Records
。更多的例子可以在这里找到Programming Examples
。
3.14布尔
Erlang中没有布尔数据类型。相反,原子true
和false
用于表示布尔值。
例子:
1> 2 =< 3.
true
2> true or false.
true
3.15转义序列
在字符串和引用原子中,下列转义序列被识别:
序列 | 描述 |
---|---|
\ b | 退格 |
\ d | 删除 |
\和 | 逃逸 |
\F | 换页 |
\ n | 新队 |
\ r | 回车 |
\ S | 空间 |
\ t | 标签 |
\ v | 垂直选项卡 |
\ XYZ,\ YZ,\ Z | 带八进制表示的字符XYZ,YZ或Z |
\ XXY | 带十六进制表示的字符XY |
\ x {X ...} | 带十六进制表示的字符; X ...是一个或多个十六进制字符 |
\ ^ a ... \ ^ z \ ^ A ... \ ^ Z | 控制A来控制Z. |
\' | 单引号 |
\” | 双引号 |
\ | 反斜杠 |
3.16型转换
有许多用于类型转换的BIF。
例子:
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