出于需要 Perl 内部知识的原因。
当您将数字4 存储为标量时,它可以存储为有符号整数、无符号整数或浮点数。你不知道哪个被使用,你没有任何理由关心哪个被使用。 Perl 会根据需要自动转换。
字符串也是同样的情况。它们有两种存储格式。你的名字就是最好的例子。 “Håkon Hægland”可以存储为
48.E5.6B.6F.6E.20.48.E6.67.6C.61.6E.64
或作为
48.C3.A5.6B.6F.6E.20.48.C3.A6.67.6C.61.6E.64
名为UTF8 的标志表示存储格式的选择。这对用户是透明的(或者至少应该是透明的)。
$ perl -Mutf8 -E'
$_ = "Håkon Hægland";
utf8::downgrade( $d = $_ ); # Converts to the first format mentioned above.
utf8::upgrade( $u = $_ ); # Converts to the second format mentioned above.
say $d eq $u ? "eq" : "ne";
'
eq
虽然它对您是透明的,但它对 Perl 本身却远非透明。每当您操作字符串时,Perl 都必须检查它以哪种存储格式存储。例如,如果你连接两个字符串,Perl 必须在执行连接之前确保它们使用相同的存储格式,并在必要时转换一个。
它对 PerlIO 也不透明。 PerlIO 与 Perl 的其余部分一样,必须处理字符串缓冲区中的字节,而不是您在 Perl 级别看到的内容。有时,这些字节注定是清除了UTF8 标志的标量的字符串缓冲区,有时,这些字节注定是设置了UTF8 标志的标量的字符串缓冲区。 PerlIO 需要跟踪它。当通过从句柄读取获得的标量需要设置UTF8 标志时,PerlIO 不会在层与层之间携带标志,而是添加:utf8 层。
所以,:encoding 转换了形成的字节
Håkon Hægland
从指定编码到
48.C3.A5.6B.6F.6E.20.48.C3.A6.67.6C.61.6E.64
而:utf8 会导致标量设置UTF8 标志,从而导致生成的标量包含
U+0048.00E5.006B.006F.006E.0020.0048.00E6.0067.006C.0061.006E.0064