我想让一个变量引用它自己的内容,所以我这样做了:
$x=\$x;
但这并不像我预期的那样工作,
$x
成为对自身的引用,所以 $$x
与 $x
相同.我期待的是$$x
成为原始字符串。为什么会这样,我应该如何在不复制 $x
中的字符串的情况下正确编写它?因为在某些情况下 $x
可以是一个巨大的字符串。
最佳答案
你问的是不可能的。变量不能同时包含引用和字符串。您必须使用两个变量。这给您留下了两个选择。
将引用存储在新变量 中
$ perl -e'
use feature qw( say );
my $x = "abc";
my $y = \$x;
say $y;
say $$y;
'
SCALAR(0x232a398)
abc
很好,简单,高效,并且不会混淆变量在什么时间包含的内容。
这种方法的缺点是引用了原始
$x
不会看到变化。然而,很难想象这种情况会很重要。请注意,新变量甚至可以与旧变量具有相同的名称。我不推荐这样做,因为它会造成不必要的困惑和容易出错。
$ perl -e'
use feature qw( say );
my $x = "abc";
my $x = \$x;
say $x;
say $$x;
'
SCALAR(0x232a398)
abc
将该值存储在新变量 中
$ perl -e'
use feature qw( say );
my $x = "abc";
$x = \( my $container = $x );
say $x;
say $$x;
'
SCALAR(0x175cbe0)
abc
这种方法的缺点是它涉及复制字符串。然而,这只是直到 5.20 的情况。 5.20 为字符串引入了写时复制机制。这意味着上面的内容实际上不会复制 5.20+ 中的字符串;它只会复制一个指针。请注意,在以下示例中,两个标量共享相同的字符串缓冲区 (
0x2ac53d0
):$ perl -MDevel::Peek -e'my $x = "abc"; my $y = $x; Dump($_) for $x, $y;' 2>&1 \
| grep -P '^(?:SV| FLAGS| PV)\b'
SV = PV(0x2a9f0c0) at 0x2abcdc8
FLAGS = (POK,IsCOW,pPOK)
PV = 0x2ac53d0 "abc"\0
SV = PV(0x2a9f150) at 0x2abcde0
FLAGS = (POK,IsCOW,pPOK)
PV = 0x2ac53d0 "abc"\0
虽然
$x = \"$x"
已被建议作为 $x = \( my $container = $x );
的较短版本,它强制字符串化,并复制整个字符串,即使在支持 COW 的 Perl 版本中也是如此。
关于string - 使变量引用其自己的字符串内容,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46325121/