【问题标题】:Are Perl strings immutable?Perl 字符串是不可变的吗?
【发布时间】:2011-03-24 15:11:45
【问题描述】:

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

my $short = 'short';
$short .= 'cake';

Perl 是有效地创建一个新字符串,然后为其分配正确的变量引用,还是 Perl 字符串本质上总是可变的?

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

【问题讨论】:

  • perldoc 中的任何可靠参考将不胜感激。
  • 可靠的引用可能对某些人来说太可靠了:perldoc perlguts 并在SvGROW 周围寻找。否则,@eugene 的回复就是您要查找的回复。
  • substrperlfunc 文档(作为左值和 4 参数调用)描述了修改字符串本身:增长、缩小和替换部分。

标签: perl string


【解决方案1】:

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

注意第三种情况没有分配新的缓冲区。

【讨论】:

  • Perl 使用 realloc,它可能会也可能不会获得一个全新的缓冲区
  • 请注意,perl 为尾随的 nul 分配空间,即使它不使用它来确定长度。另请注意,它尽可能了解 malloc 库的粒度并向上舍入分配
【解决方案2】:

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

【讨论】:

  • perldoc 中是否对此有硬性引用?
  • @Zaid:不是我知道的副手
【解决方案3】:
$short = 'short';
print \$short;

$short .= 'cake';
print \$short;

执行此代码后,我得到“SCALAR(0x955f468)SCALAR(0x955f468)”。我的答案是“可变的”。

【讨论】:

  • Perl 标量实际上由两个独立的部分组成;一个固定大小,一个可选的可变大小(取决于存储的值的类型)大小。固定大小组件的地址;将可变组件换成新组件是完全合理的。但事实上并非如此。 :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-04-14
  • 2011-08-06
  • 1970-01-01
  • 2010-09-08
相关资源
最近更新 更多