在 Perl 中克隆通过引用传递的数组的最佳单行方法是什么?

What is the best one-line way to clone array passed by reference in Perl?

当通过引用将数组传递给 sub 时,我需要克隆数组,因为我不想反映 sub 的本地数组更改,所以我可以这样做:

$arrayref = shift;
$arrayref = [ map { $_ } @$arrayref ];

是否有更好、更优雅的单行方式来做到这一点?请注意通过引用传递数组并将对新数组的引用分配给同一变量。

map { $_ } 是多余的。只要做:

$arrayref = [ @$arrayref ];

您不需要 map 语句。只需使用 @ 印记取消引用您的 arrayref,使用取消引用的值创建一个新的匿名 arrayref,然后将其结果分配给某个新变量。

main::(-e:1):   0
  DB<1> $a = [1,2,3];

  DB<2> x $a;
0  ARRAY(0x7fe7cb80bd78)
   0  1
   1  2
   2  3
  DB<3> $b = [ @$a ];

  DB<4> x $b;
0  ARRAY(0x7fe7cc0b9da0)  # < different address
   0  1
   1  2
   2  3

您也可以将其包装在一个简单的子程序中:

sub clone {
   my $arrayref = shift; 

   croak 'Supplied argument is not an arrayref'
      unless $arrayref && ref($arrayref) eq 'ARRAY';

   return [ @$arrayref ];
}

注意:如果您的数据结构超过 1 层(例如多维数组),此解决方案将不起作用,因为内部引用将保持不变。 CPAN 上有一个名为 Clone 的不错的模块,可以很好地处理嵌套数据结构。

一条命令即可完成所有操作:

my $clonedref = [ @{ shift() } ];

注意它只克隆数组引用的顶层,即如果数组中嵌套了结构,它们将不会被克隆。