Perl 处理 UTF-8 确实需要开发者对编码有清晰的认识和显式的操作,这有时会让人觉得比某些其他语言要“麻烦”一些。这主要是因为 Perl 的历史发展和其强大的文本处理能力,它允许你在字节层面和字符层面进行精细操作,但也因此需要你明确告知 Perl 如何解释和处理不同来源的文本数据。

我们来逐一解析你提到的这些技术点:

1. use utf8;

2. use open qw(:std :utf8);

3. binmode(STDOUT, ':utf8'); (以及其他文件句柄)

4. open my $fh, '<:utf8', $json_file;

现在来回答你的具体困惑:

总结与建议:

对于你的场景(终端UTF-8,输入文件UTF-8,源代码可能含UTF-8,输出UTF-8):

  1. 始终使用 use utf8; 在脚本开头,如果你的源代码包含非 ASCII 字符。
  2. 强烈建议使用 use open qw(:std :utf8); 在脚本开头,这将为你处理好标准I/O和大部分文件的默认编码问题。
  3. 对于打开特定文件(如你的 JSON 文件),你可以选择:
    • 依赖 use open 的默认行为:open my $fh, '<', $json_file;
    • 或者显式指定,以求清晰和绝对保证:open my $fh, '<:utf8', $json_file; (个人更倾向于这种,尤其对于明确知道编码的文件)。
  4. 在使用了 use open qw(:std :utf8); 的情况下,通常不需要再对 STDIN, STDOUT, STDERR 使用 binmode,除非有特殊原因。

Perl 的这种明确性要求,虽然初看起来步骤多,但它也赋予了开发者处理各种复杂编码场景的灵活性。一旦掌握了这些基本工具的用途,处理 UTF-8 就会变得系统化。其他语言可能通过更统一的字符串类型和更“智能”的默认行为来简化常见场景,但这有时也可能隐藏了编码转换的细节,当出现问题时反而更难排查。