使变量引用自己的字符串内容

时间:2017-09-20 14:42:47

标签: string perl reference

我想让变量引用自己的内容所以我这样做了:

$x=\$x;

但这不符合我的预期,$x成为对自身的引用,因此$$x$x相同。我期待的是$$x成为原始字符串。为什么这样,如果不在$x中复制字符串,我应该如何正确地编写?因为在某些情况下$x可能是一个巨大的字符串。

2 个答案:

答案 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";