【发布时间】:2015-04-22 02:07:51
【问题描述】:
当通过引用将数组传递给子时,我需要克隆数组,因为我不想将本地数组更改反映在子之外,所以我可以这样做:
$arrayref = shift;
$arrayref = [ map { $_ } @$arrayref ];
有没有更好、更优雅的单行方式来做到这一点?请注意有关通过引用传递数组并将对新数组的引用分配给同一变量。
【问题讨论】:
标签: perl clone argument-passing
当通过引用将数组传递给子时,我需要克隆数组,因为我不想将本地数组更改反映在子之外,所以我可以这样做:
$arrayref = shift;
$arrayref = [ map { $_ } @$arrayref ];
有没有更好、更优雅的单行方式来做到这一点?请注意有关通过引用传递数组并将对新数组的引用分配给同一变量。
【问题讨论】:
标签: perl clone argument-passing
map { $_ } 是多余的。做吧:
$arrayref = [ @$arrayref ];
【讨论】:
您不需要 map 语句。只需使用@ sigil 取消引用您的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() } ];
注意它只克隆数组引用的顶层,即如果数组中嵌套了结构,它们将不会被克隆。
【讨论】: