我想让变量引用自己的内容所以我这样做了:
$x=\$x;
但这不符合我的预期,$x
成为对自身的引用,因此$$x
与$x
相同。我期待的是$$x
成为原始字符串。为什么这样,如果不在$x
中复制字符串,我应该如何正确地编写?因为在某些情况下$x
可能是一个巨大的字符串。
答案 0 :(得分:4)
你问的是不可能的。变量不能同时包含引用和字符串。您必须使用两个变量。这为您提供了两个选项。
将参考文献存储在新变量中
$ 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"\0
SV = PV(0x2a9f150) at 0x2abcde0
FLAGS = (POK,IsCOW,pPOK)
PV = 0x2ac53d0 "abc"\0
虽然$x = \"$x"
被建议为$x = \( my $container = $x );
的较短版本,但它会强制进行字符串化,并且它会复制整个字符串,即使在支持COW的Perl版本中也是如此。
答案 1 :(得分:1)
分配对值的引用,而不是变量:
my $string = 'abcefgh';
$string = \ "$string";
print $$string, "\n";