erlang 位语法/比特语法(bit syntax)

Erlang的比特语法(Erlang Bit Syntax)提供了一种方法来匹配二进制数据,这使得Erlang二进制对象在某种程度上等同于其他Erlang对象,如元组和列表。也因为其快速高效,使得在Erlang中,二进制对象被广泛使用,尤其是在协议编程方面。(官方文档)

Erlang的比特语法表达式:

<<>> 
<<E1,...,En>>

每个元素Ei指定了一段二进制串(bit string)。每个元素Ei都是一个值,后面可以带有可选参数Size、TypeSpecifierList

Ei = Value |
     Value:Size |
    Value/TypeSpecifierList |
    Value:Size/TypeSpecifierList

Size表示前一个Value数据存储的位数,默认是8位,也就是一个字节。

TypeSpecifierList可以是以下几种类型及其组合,组合以 - 相连

Type = integer | float | binary | bytes |bitstring | bits | utf8 | utf16 | utf32

       默认值是integer。bytes是binary的简写,bits是bitsring的简写

Signedness = signed | unsigned

       只有当type为integer时有用,默认是unsigned

Endianness = big | little | native

       当type为integer,utf16,utf32,float有用,默认是big

Unit = unit:IntegerLiteral

       有效范围是1-256,integer、float和bitstring默认是1,binary默认是8

例如:

-define( UINT, 32/unsigned-little-integer).
-define( INT, 32/signed-little-integer).
-define( USHORT, 16/unsigned-little-integer).
-define( SHORT, 16/signed-little-integer).
-define( UBYTE, 8/unsigned-little-integer).
-define( BYTE, 8/signed-little-integer).
-define( CHAR, 1/binary-unit:8).

在官方文档找到以下一段代码:

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,2,10:4>>
12> H.
<<17,2,10:4>>

 

例子说明:

1、例子1和2:从一组常量或一个字符串来构造二进制对象

1> Bin1 = <<1,17,42>>.
2> Bin2 = <<"abc">>.

以上生成的二进制大小为3。binary_to_list(Bin1) 得到 [1, 17, 42],binary_to_list(Bin2) 得到[97, 98, 99]。数字常量是在0-255之间的整数,用8位存储,如果超过这个范围后面加:Size来说明,如<<256:16>>。字符则会转化为ASCII码。

 

2、例子3:从一组限定边界的变量来构造二进制对象

3> Bin3 = <<1,17,42:16>>.

以上生成的二进制大小为4。

上面,我们给42指定了16位的大小来储存,所以在内存中的数据为0000 0000 0010 1010,这样构成出来的对象就是<<0, 42>>


3、例子4、6:按照某种形式匹配二进制对象

4> <<A,B,C:16>> = <<1,17,42:16>>.
6> <<D:16,E,F>> = <<1,17,42:16>>.

例子4很好理解,这里说一下例子6吧,为何D会得到273的结果?

<<1,17,42:16>>生成的二进制数据前面说过了,为<<1,17,0,42>>

D:16表示匹配内存中16位的二进制数据,所以的到就是<<1,17>>在内存中的数据,为0000 0001 0001 0001,结果就是256 + 16 + 1,也就是273


4、例子11:也是从一组限定边界的变量来构造二进制对象,和例子3不同的是大小不是8的倍数。

<<1,17,42:12>>.

上面,我们给42指定了12位的大小来存储,所以在内存中的数据为0000 0010 1010,

这样构造出来的对象就是<<2,10:4>>

在erlang 二进制中,对象默认以8位为一个单位来表示,不足就向后面借位,比如:<<42:12,1,17>>生成的二进制对象是<<2,160,17,1:4>>,其实两者表达的是一段相同的二进制数据。


注意:

 "B=<<1>>" 在erlang中被解释成 "B =< <1>>",这会引起一个语法错误“syntax error before: '<'”。正确的做法是写成 "B = <<1>>" 


binary与bitstring的区别?

erlang文档有说明:

A bitstring is a sequence of zero or more bits, where the number of bits does not need to be divisible by 8. If the number of bits is divisible by 8, the bitstring is also a binary.

就是说,binary也是bitstring的一种,当二进制串大小能被8整除,就是binary


什么情况下会区分?

如模式匹配:

foo(<<A:8,Rest/binary>>) ->
	{binary, A, Rest};
foo(<<A:8,Rest/bitstring>>) ->
	{bitstring, A, Rest}.


2015/7/17 补充binary与bitstring的区别

参考:http://blog.csdn.net/mycwq/article/details/11529755

你可能感兴趣的:(erlang,bit)