Erlang数据类型

Erlang提供的数据类型,包括以下几种:

基本类型

  • 数字(Number)
    数字类型又包含整数(integers)和浮点数(floats)类型,其中整数是精确的而且是支持大数的,小数是满足IEEE754规则的64位浮点数。Erlang支持ASCII或者Unicode转换成整数值,同时支持整数不同进制的表示。(‘%’后的内容为注释)

1> $a.  %% ASCII表中的a是97
97
2> $哈.
21704
3> $\n.
10
4> 2#100.  %% 用100表示的二进制是4
4
5> 4#100.
16
6> 16#100.
256

  • 原子(Atom)
    原子可以理解为一个不可变的常量,必须以小写字母开头,如果要以大写、下划线或者其他的特殊字符开头,必须加上单引号。原子在Erlang里面是存在一张表上面的,原子的个数有上限,大概是在一百万个左右。

test
'Myhome'
'_hero'

  • 位串和二进制(Bit Strings and Binaries)
    在大多数情况下,二进制型里的位数都会是8的整数倍,因此对应一个字节串。如果位数不是8的整数倍,就称这段数据为位串(bitstring)。所以当我们说位串时,是在强调数据里的位数不是8的整数倍。位语法是一种表示法,用于从二进制数据里提取或加入单独的位或者位串。当你编写底层代码,以位为单位打包和解包二进制数据时,就会发现位语法是极其有用的。

1> <<257,1,2,3,5>>.   %%二进制型的元素如果大于8位的会自动截断,257截断成1
<<1,1,2,3,5>>
2> <<0:7,1:2>>.   %%二进制型位数如果不是8的整数倍就会产生位串,这边多了1位1
<<0,1:1>>
3> <<0:3,0:4,1:2>>.
<<0,1:1>>

  • 引用(Reference)
    可以通过make_ref/0函数来创建一个引用,引用在Erlang程序运行时调用make_ref函数产生的是全局唯一的。比如timer模块在创建一个定时任务的时候通常会返回一个引用,可以通过这个引用来取消定时任务。
  • 函数(Fun)
    函数在Erlang里面也算是一种数据类型,通过给变量绑定函数,可以通过变量名来执行函数。

1> Fun = fun(X) -> X * X end.

Fun<erl_eval.6.50752066>

2> Fun(9).
81

  • 端口标识符(Port Identifier)
    端口用于与外界通信,由通过函数open_port/2来创建。消息可以通过端口进行收发,但是这些消息必须遵守所谓“端口协议”(port protocol)的规则。
  • 进程标识符(Pid)
    当创建一个进程的时候会产生一个进程标识符,可以通过这个进程标识符和进程进行通讯。

1> Process1 = spawn(fun() -> receive X -> io:format("recv ~p, bye~n", [X]) end end).
<0.34.0>  %% 创建一个进程等待接收消息
2> Process1 ! my_test.  %% 给进程发消息
recv my_test, bye
my_test

复合类型

为了方便定义以下的这些复合类型,我把上述的所有基本类型都称为Term。

  • 元组(Tuple)
    元组类似于C语言里面的结构体(Struct),是由固定数量的元素组成的复合数据类型,可以定义成如下结构:

{Term1, Term2, ..., TermN}

可以通过模式匹配或者element/2函数来提取元组里面元素的值,通过setelement/3来设置元组里面元素的值,size可以取元组里面元素的个数。

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> size(P).
3
6> {adam, Old, {Month, Day}} = P.
{adam,24,{july,29}}
7> Old.
24

  • 映射组(Map)
    映射组是一个由多个Key-Vaule结构组成的符合数据类型,可以定义为如下结构:

{Key1=>Value1, Key2=>Value2, ..., KeyN=>ValueN}

其中Key、Value都是Term

可以通过maps模块提供的一些函数对映射组进行操作

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

  • 列表(List)
    列表类似于其他语言里面的数组,是由可变数量的元素组成的复合数据结构,可以定义成如下结构:

[Term1, Term2, ..., TermN]

在Erlang里面,列表由一个头和一个尾组成,空列表也是一个列表。所以列表也可以有一个递归的定义

List = [Term| List] | []
[] 是一个列表, 因此
[c|[]] 是一个列表, 因此
[b|[c|[]]] 是一个列表, 因此
[a|[b|[c|[]]]] 是一个列表, 或者简写为 [a,b,c]

lists模块可以提供大量函数对列表进行操作:

1> L = [3,3,4,2,1,2,34].
[3,3,4,2,1,2,34]
2> length(L).
7
3> lists:sort(L).
[1,2,2,3,3,4,34]
4> lists:reverse(L).
[34,2,1,2,4,3,3]

其他类型(不算数据类型)

  • 字符串(String)
    字符串用一对双引号括起来,但不算是Erlang中的数据类型。字符串仅仅是列表的一个缩写,比如:字符串"hello"是列表[$h,$e,$l,$l,$o]的一个缩写。两个相邻的字符串在编译的时候连接成一个字符串,不会造成任何运行时开销。

1> "hello" " " "world".
"hello world"

  • 记录(Record)
    记录其实就是元组的另一种形式。通过使用记录,可以给元组里的各个元素关联一个名称。对记录的处理是在编译的时候完成的,在运行时是不会有记录的,可以把记录理解成是元组的一种语法糖。
-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}

  • 布尔类型(Boolean)
    在Erlang中没有Boolean类型。而是用原子true和false来表示布尔值。

1> 2 =< 3.
true
2> true or false.
true

类型转换

Erlang提供了一些内置的类型转换函数,可以方便地进行类型转换,下面是一些类型转换的例子:

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

最后更新时间:2017-04-30 19:11:25
转载请注明出处,Darcy's Blog https://lintingbin2009.github.io/2017/04/30/Erlang数据类型/

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,132评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,802评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,566评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,858评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,867评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,695评论 1 282
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,064评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,705评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,915评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,677评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,796评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,432评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,041评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,992评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,223评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,185评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,535评论 2 343

推荐阅读更多精彩内容