Erlang中的原子、字符串和二进制串
Erlang中的原子(Atom), 字符串(String)和二进制串(Binary)是有点容易让人糊涂 的东西, 这里归纳一下它们之间的区别与联系。
原子
原子是由小写字母开头, 后接大小写字母及数字及下划线的, 比方说abc, cDE, ff89, 或是由单引号’‘括起来的任意字符, 比方说’EXIT’, ‘!@#@!$sdaf’。 用过其他语言的话, 会觉得Erlang中没括起来的原子长得像变量, 括起来的 长得像字符串, 但其实都不是, 这点要特别注意。Erlang中的变量是以大写字母 开头的, 字符串是用双引号括起来的。
原子在Erlang中应用非常广, 模块名、函数名、记录名都是原子, 所以如果你够蛋疼的话, 可以用’!#@$#y3fdsa1’(包括两边的单引号)当做函数名。
原子顾名思义是“不可分割”的东西, 原子无论长短, 在内存中占用的空间都是一样的,
然而, 原子的名字也不是毫无意义的, 可以利用atom_to_binary
把原子名转成二进制串,
也可以用atom_to_list
把原子名转成字符串。
反过来也可以, 有binary_to_atom
和list_to_atom
可以用。
Erlang中是没有原生的原子连接方法, 真想要相连的话, 先要转成二进制串或是字符串.
字符串
Erlang中字符串是使用双引号括起来的一串字符, 例如”string”, “123”等等。 双引号其实只是一个简写形式, 其实并没有把“字符串”当作一种独立的数据类型, 而是用正整数的列表(List)作为字符串使用, 跟C里面的做法相似。以下三行是等价的:
"hello"
[$h, $e, $l, $l, $o]
[104,101,108,108,111]
因此字符串转换成原子及二进制串的的函数名为list_to_atom
和list_to_binary
。
Erlang中的有专门处理字符串的模块, string
, 可以用以进行大小写变换、截断、
对齐、连接、分割、子字符串等等常用操作。由于字符串实质上是列表, 因此lists
模块里的方法也全都适用于字符串。
字符串是列表, 因此可以使用列表的连接运算符++
进行连接。二进制串是不可以用++
的。
虽然拿 字符串++二进制串
在语法上是允许的, 但得到的结果是一个 “非正规列表”
(也有人翻译成 “非严格列表” ), 是不推荐这么做的。
二进制串
二进制串是Erlang的一项特色, 使用在代码中使用<< >>
括起来(看起来有点像中文的
书名号, 其实是两个小于号和两个大于号)。括起来的内容可以用数字表示, 或是用对应
的字符串表示, 如下:
<< 97, 98, 99 >>
<< "abc" >>
这两者含义是相同的。但要注意的是, 和列表[ ]
或元组{ }
不一样的是,
双引号只是一种简记方式, 并不是说把一个字符串放到<< >>
里就会变成二进制串的,
比方说以下的写法都是不对的。
<< [97, 98, 99] >>
A = "abc", << A >>
正确的做法是:
A = "abc",
A1 = list_to_binary(A),
<< A1/binary >>,
%% 或者
<< (list_to_binary(A))/binary >>,
记住, 在二进制串中使用函数的话, 必须要用括号括起来.
<< >>
里可以接受数字和二进制串, 利用所谓的比特语法构造二进制串或进行模式匹配。
格式为 变量:大小/类型
, 例如:
X:4/little-signed-integer-unit:8 %% 把X存为有符号小端整数, 大小为 4*8 bit
A:32/integer %% 把A存储为32位整数
B:15/binary %% 要求B是长于或等于15字节的二进制串, 截取B的前15字节
变量:大小/类型
的格式中, 大小和类型是可以省略的, 因此可以有:
变量:大小
变量/类型
变量
当进行省略时, 会使用默认值:
-
缺省的类型是整数 ( 手册 上的例子是有点问题的, «3.14»这样的写法在 Erlang 16B 版上是非法的).
-
缺省的大小与类型有关:
整数是8位, 溢出部分被截掉: 例如
<< 257 >>
等价于<< 257:8 >>
, 值等于<< 1 >>
浮点数是64位
二进制串是整个串的长度: 例如
<< A/binary >>
会把整个A都存起来. -
对于整数, 缺省是无符号的.
-
对于整数, 缺省是大端的(big-endian).
-
可以使用
-unit:长度
的方式来指定单位长度, 缺省的单位长度与类型有关.整数(integer)/浮点数(float)/字节串(bitstring) 的缺省长度是1.
而binary类型缺省长度是8.
二进制的连接直接在<< >>
中使用逗号放一起就可以了, 例如
<< A/binary, B/binary >>,
<< 1234:32, "String", "中文也可以", "引号的后面不能加/binary", <<"但是二进制串中括另一个二进制串要指定格式">>/binary >>
其它的二进制语法, 例如二进制中的模式匹配/二进制解析, 等等, 就不在这里讲了.
参考:
blog comments powered by Disqus