Perl 如何在内存中存储整数?

use*_*135 5 perl

say pack "A*", "asdf";           # Prints "asdf"
say pack "s", 0x41 * 256 + 0x42; # Prints "BA" (0x41 = 'A', 0x42 = 'B')
Run Code Online (Sandbox Code Playgroud)

第一行是有道理的:您正在获取一个 ASCII 编码的字符串,将其作为 ASCII 字符串打包成一个字符串。在第二行中,压缩形式是“\x42\x41”,因为我的机器上短整数的字节序很小。

但是,我不能动摇我应该能够将第二行中的打包字符串视为数字的感觉,因为(我假设)Perl 就是这样存储数字的,作为小端字节序。有没有不拆包的方法呢?我正在尝试为 pack() 返回的东西获得正确的心理模型。

例如,在 C 中,我可以这样做:

#include <stdio.h>

int main(void) {
    char c[2];
    short * x = c;
    c[0] = 0x42;
    c[1] = 0x41;

    printf("%d\n", *x); // Prints 16706 == 0x41 * 256 + 0x42
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

JB.*_*JB. 2

我将其视为pack序列化函数。它采用 Perl 值作为输入,并输出序列化形式。事实上,输出序列化形式恰好是 Perl 字节串,这更多的是实现细节而不是核心功能。

因此,您真正希望对结果字符串做的就是将其解压,尽管序列化形式可以方便地让它在进程、主机、行星之间移动。

如果您有兴趣将其序列化为数字,请考虑使用vec

say vec "BA", 0, 16;  # prints 16961
Run Code Online (Sandbox Code Playgroud)

要仔细查看字符串的内部表示,请查看Devel::Peek,尽管对于纯 ASCII 字符串您不会看到任何令人惊讶的内容。

use Devel::Peek;
Dump "BA";

SV = PV(0xb42f80) at 0xb56300
  REFCNT = 1
  FLAGS = (POK,READONLY,pPOK)
  PV = 0xb60cc0 "BA"\0
  CUR = 2
  LEN = 16
Run Code Online (Sandbox Code Playgroud)