在一个和某个巨大的 DBM 文件捆绑的散列上使用 values 也肯定会生成一个巨大的列表,导致你拥有一个巨大的进程。你可能应该使用 each 函数,它会一个一个地遍历散列记录,而不会把它们的所有东西都吞进一个庞大的,哦,应该是巨大的列表里。
vec EXPR, OFFSET, BITS
vec 函数制造一个存储紧凑的无符号整数的列表。这些整数在一个普通的 Perl 字串里尽可能紧密的绑在一起。EXPR 里的字串被当作一个位串对待,该未串是用若干元素组成的,而元素的数目取决于字串的长度。
OFFSET 声明你关心的特定元素的索引。读和写元素的语法是一样的,因为 vec 根据你是在左值环境还是右值环境里来存储和恢复元素值。
BITS 声明每个元素以位计算的时候宽度是多少,它必须是二的幂:1,2,4,8,16,或 32(有些平台上还有 64)。(如果声明了任何其他数值,那么就会抛出一个例在 0 .. (2**BITS)-1 的整数。对于小一些的尺寸,那么每个字节里都会尽可能多的打包进去元素。如果 BITS 是 4,那么每个字节里有两个元素(通常它们被称为半字节(nybble))。等等。大于一个字节的整数是以大头在前的字节序存储的。
一个无符号整数列表可以存储在一个标量变量里,方法是把它们分别赋予 vec 函数。scalar() perl(如果 EXPR不是一个合法的左值,那么抛出一个错误。)在随后的例子里,那些元素是 4 位宽:
$bitstring = "";
$offset = 0;
foreach $num (0, 5, 5, 6, 2, 7, 12, 6) {
vec($bitstring, $offset++, 4) = $num;
}
如果一个元素超出了它要写的字串的结尾,那么 Perl 先用足够的零内容字节扩展该字串。
存储在标量变量里的向量然后就可以通过声明正确的 OFFSET 来检索:
$num_elements = length($bitstring)*2; # 每个字节 2 元素
foreach $offset (0 .. $num_elements-1) {
print vec($bitstring, $offset, 4), "\n";
}
如果选择的元素超出了字串的结尾,那么返回 0。
用 vec 创建的字串还可以用逻辑操作符 |,&,^,和 ~ 操作。如果两个操作数都是字串,那么这些操作符将假定需要进行的是位串操作。参阅第三章,单目和双目操作符,“位操作符”一节里的例子。
如果 BITS == 1,那么就可以创建一个所有位都存储在一个标量里的位序列。顺序是这样的,vec($bitstring, 0,1) 保证进入字串里的第一个字节的最低位。
@bits = (0,0,1,0, 1,0,1,0, 1,1,0,0, 0,0,1,0);
$bitstring = "";
$offset = 0;
foreach $bit (@bits) {
vec($bitstring, $offset++, 1) = $bit;
}
print "$bitstring\n"; # "TC", 也就是 '0x54', '0x43'
一个位串可以通过声明一个“b*”模板给 pack 或者 unpack 从一串 1 和 0 转换过来,或者是转换成这些 1 和 0 的字串。另外,pack 可以和“b*”模板一起使用从一个 1 和 0 的字串创建一个位串。该顺序和 vec 需要的顺序是兼容的。
本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/jisuanjixue/article-28372-28.html
吸取教训