我想制作一个变量引用自己的内容,所以我这样做了:
$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
的引用不会看到更改。但是很难想象这可能很重要。
请注意,新VAR甚至可以具有与旧名称相同的名称。我不建议这样做,因为这是不必要的混淆和错误的。
$ 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"
SV = PV(0x2a9f150) at 0x2abcde0
FLAGS = (POK,IsCOW,pPOK)
PV = 0x2ac53d0 "abc"
虽然$x = "$x"
被建议用作$x = ( my $container = $x );
的较短版本,但它会强制弦乐化,并且它复制了整个字符串,即使是在支持牛的Perl版本中。
分配对该值的引用,而不是变量:
my $string = 'abcefgh';
$string = "$string";
print $$string, "n";