Perl字符串是不可变的吗?

Zai*_*aid 16 string perl

当我对字符串进行连接时,幕后发生了什么?

my $short = 'short';
$short .= 'cake';
Run Code Online (Sandbox Code Playgroud)

Perl是否有效地创建了一个新字符串,然后为它分配了正确的变量引用,或者Perl字符串本质上是否可变?

这个问题的动机来自我与一位同事的讨论,他说脚本语言可以使用不可变的字符串.

Eug*_*ash 20

Perl字符串可变的.如果需要,Perl会自动创建新缓冲区.

use Devel::Peek;
my $short = 'short';

Dump($short);
Dump($short .= 'cake');
Dump($short = "");

SV = PV(0x28403038) at 0x284766f4
  REFCNT = 1
  FLAGS = (PADMY,POK,pPOK)
  PV = 0x28459078 "short"\0
  CUR = 5
  LEN = 8
SV = PV(0x28403038) at 0x284766f4
  REFCNT = 1
  FLAGS = (PADMY,POK,pPOK)
  PV = 0x28458120 "shortcake"\0
  CUR = 9
  LEN = 12
SV = PV(0x28403038) at 0x284766f4
  REFCNT = 1
  FLAGS = (PADMY,POK,pPOK)
  PV = 0x28458120 ""\0
  CUR = 0
  LEN = 12
Run Code Online (Sandbox Code Playgroud)

请注意,在第三种情况下没有分配新的缓冲区.

  • Perl使用realloc,它可能会也可能不会获得全新的缓冲区 (2认同)

yst*_*sth 12

Perl字符串肯定是可变的.除了使用的长度和起始偏移之外,每个都将存储分配的缓冲区大小,并且将根据需要扩展缓冲区.(开始偏移对于允许像s/^ abc //这样的消耗操作不必移动实际数据很有用.)