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



我想制作一个变量引用自己的内容,所以我这样做了:

$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";

相关内容

最新更新