Erlang学习: 比特语法

本文详细介绍了Erlang中用于处理二进制数据的比特语法,包括如何将字符串转换为二进制数据,如何从二进制数据中提取特定部分,并展示了如何进行模式匹配来获取特定的字节值。同时,文章还讨论了模式匹配中可能出现的错误及其解决方法。

转载自:http://fsword.iteye.com/blog/1110496

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

 

废话少说,看例子:

 

Erlang代码   收藏代码
  1. Eshell V5.8.4  (abort with ^G)  
  2. 1> X = "hello".  

 

先定义一个字符串变量X,下面把它变成二进制数据

Erlang代码   收藏代码
  1. 2> BinX = list_to_binary("hello").  
  2. <<"hello">>  

 

这里的 list_to_binary 是erlang的内建函数,专业术语叫 BIF ( Build-in Function),通过它,我们得到了一个二进制数据 BinX 。

字节流实际上就是一个二进制比特数组,相对应,直接将binary数据变回来的函数叫 binary_to_list:

Erlang代码   收藏代码
  1. 3> binary_to_list(BinX).  
  2. "hello"  

到此为止都很简单,下面看看 erlang  的魔力:

 

Erlang代码   收藏代码
  1. 4> <<First:8,Body:24,Last:8>> = BinX.  
  2. <<"hello">>  
  3. 5> First.  
  4. 104  
  5. 6> Body.  
  6. 6646892  
  7. 7> Last.  
  8. 111  
 

仔细看看,这不就是二进制版的模式匹配么(变量后面用冒号分隔的是截取的二进制数据位长度 )。经过这个变化后,First就存放了第一个字符(二进制数据前八位) ”h” 的ascii码,Last存放了最后一个字符(二进制数据的后八位) “o” 的 ascii 码,Body 有些不同,它对应了中间的 24 位(8位一个字节,三个字节就是24位)数据,因此看起来不像是一个 ascii 编码范围内的整数

 

现在把它们转变成字符串——

Erlang代码   收藏代码
  1. 8> binary_to_list(First).  
  2. ** exception error: bad argument  
  3.      in function  binary_to_list/1  
  4.         called as binary_to_list(104)  
 

出现错误,为什么呢?

因为binary_to_list接受的是一个binary数据,而First本身已经是一个整数了,所以是参数错误,解决办法可以是这样

Erlang代码   收藏代码
  1. 9> binary_to_list(<<First>>).  
  2. "h"  
 

这样很麻烦,实际上,更好的办法是在模式匹配的时候就说清楚我们需要的是一个binary而不是integer,这一点erlang已经想到了,重新做一下是这样的——

Erlang代码   收藏代码
  1. 10> <<First2:1/binary,Body2:3/binary,Last2:1/binary>> = BinX.  
  2. <<"hello">>  
  3. 11> binary_to_list(First2).                                    
  4. "h"  
  5. 12> binary_to_list(Body2).   
  6. "ell"  
  7. 13> binary_to_list(Last2).  
  8. "o"  

 

这里表示长度的数字有些变化,对于binary,它表示的是二进制字节数(之前是比特数)。

 

模式匹配的时候,如果最后一个变量长度为一个字节,那么是可以省略的——

Erlang代码   收藏代码
  1. 14> <<First3:8,Body3:24,Last3>> = BinX.  
  2. <<"hello">>  
 

另外补充一点:一开始使用比特匹配的时候常常会遇到下面的错误

Erlang代码   收藏代码
  1. 15> <<First4:8, Body4:16, Last3:8>> = BinX.  
  2. ** exception error: no match of right hand side value <<"hello">>  

 

这是因为左侧的表达式总字节数与右侧不符(8+16+8 != 5 * 8 ),这一点需要多加注意,常见的情况是错误的估计了右侧变量的比特数。

 

Text代码   收藏代码
  1. 附注:  
  2.   
  3. 完整的比特语法:  
  4. <<>> %%表示一个空的二进制数据  
  5. <<E1,E2,...,En>>  
  6.   
  7. 这里每一个 Ei 表示一个二进制数据区块。区块可能的形式有四种:  
  8.   
  9. Ei = Value |  
  10.   
  11.        Value:Size |  
  12.   
  13.        Value/TypeSpecifierList |  
  14.   
  15.        Value:Size/TypeSpecifierList  

其他参考资料:

http://erlang.chaoskey.com/05/03

http://0x55aa.sinaapp.com/%E7%AE%97%E6%B3%95-%E7%BC%96%E7%A8%8B/600.html

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值