在网络编程中,我们面对的不再是字符串,而是字节流,对于这些信息的处理,erlang提供了比特语法这样的工具。

 
看例子:
 
 
  
  1. Erlang代码 
  2. Eshell V5.8.4  (abort with ^G)   
  3. 1> X = "hello".   

 
先定义一个字符串变量X,下面把它变成二进制数据
 
 
 
  
  1. Erlang代码   
  2. 2> BinX = list_to_binary("hello").   
  3. <<"hello">>   
 
这里的 list_to_binary 是erlang的内建函数。
字节流实际上就是一个二进制比特数组,相对应,直接将binary数据变回来的函数叫 binary_to_list:
 
 
 
  
  1. Erlang代码   
  2. 3> binary_to_list(BinX).   
  3. "hello" 
 
到此为止都很简单,下面看看 erlang  的魔力:
 
 
 
  
  1. Erlang代码   
  2. 4> <<First:8,Body:24,Last:8>> = BinX.   
  3. <<"hello">>   
  4. 5> First.   
  5. 104   
  6. 6> Body.   
  7. 6646892   
  8. 7> Last.   
  9. 111 
  
 
仔细看看,这不就是二进制版的模式匹配么(变量后面用冒号分隔的是截取的二进制数据位长度 )。
经过这个变化后,First就存放了第一个字符(二进制数据前八位) ”h” 的ascii码,
                                Last存放了最后一个字符(二进制数据的后八位) “o” 的 ascii 码,
                                Body 有些不同,它对应了中间的 24 位(8位一个字节,三个字节就是24位)数据,
                                因此看起来不像是一个 ascii 编码范围内的整数
 
 
现在把它们转变成字符串——
 
 
 
  
  1. Erlang代码   
  2. 8> binary_to_list(First).   
  3. ** exception error: bad argument   
  4.      in function  binary_to_list/1   
  5.         called as binary_to_list(104)   
  6.   
出现错误,为什么呢?
因为binary_to_list接受的是一个binary数据,而First本身已经是一个整数了,所以是参数错误,解决办法可以是这样
 
 
  
  1. Erlang代码   
  2. 9> binary_to_list(<<First>>).   
  3. "h"   
  4.   
这样很麻烦,实际上,更好的办法是在模式匹配的时候就说清楚我们需要的是一个binary而不是integer,
这一点erlang已经想到了,重新做一下是这样的:
 
 
 
  
  1. Erlang代码   
  2. 10> <<First2:1/binary,Body2:3/binary,Last2:1/binary>> = BinX.   
  3. <<"hello">>   
  4. 11> binary_to_list(First2).                                     
  5. "h"   
  6. 12> binary_to_list(Body2).    
  7. "ell"   
  8. 13> binary_to_list(Last2).   
  9. "o"   
 
这里表示长度的数字有些变化,对于binary,它表示的是二进制字节数(之前是比特数)。
 
模式匹配的时候,如果最后一个变量长度为一个字节,那么是可以省略的——
 
 
  
  1. Erlang代码   
  2. 14> <<First3:8,Body3:24,Last3>> = BinX.   
  3. <<"hello">>   
 
另外补充一点:一开始使用比特匹配的时候常常会遇到下面的错误
 
 
  
  1. Erlang代码   
  2. 15> <<First4:8, Body4:16, Last3:8>> = BinX.   
  3. ** exception error: no match of right hand side value <<"hello">>   
 
这是因为左侧的表达式总字节数与右侧不符(8+16+8 != 5 * 8 ),这一点需要多加注意,常见的情况是错误的估计了右侧变量的比特数。
 
 
 
 
附注:  
 
 
  
  1.    
  2. 完整的比特语法:   
  3. <<>> %%表示一个空的二进制数据   
  4. <<E1,E2,...,En>>   
  5.    
  6. 这里每一个 Ei 表示一个二进制数据区块。区块可能的形式有四种:   
  7.    
  8. Ei = Value |   
  9.    
  10.        Value:Size |   
  11.    
  12.        Value/TypeSpecifierList |   
  13.    
  14.        Value:Size/TypeSpecifierList