不使用 `@tmp`,交换两个数组的元素

3

交换两个标量值非常简单,例如:

($ours, $theirs) = ($theirs, $ours);

那么,我该如何使用数组变量来实现这个呢?
# (@ours, @theirs) = (@theirs, @ours);  # XXX

# lame
my @tmp = @ours;
@ours = @theirs;
@theirs = @tmp;
2个回答

3

关于逻辑的一些内容

@ar = qw(one two three four);
@br = (1..5);
unshift(@ar,@br);
@br = splice(@ar,scalar @br);
print "@ar\n@br\n";

由于数组被展平,所以无法进行数组交换。 (@ar,@br)=(@br,@ar)

实际上,您正在创建一个新列表,该列表的元素来自两个数组。最终,您将得到一个列表。这个列表数据会覆盖第一个数组(@ar)。第二个数组应该为空(@br)。


2
Perl将所有列表展平,而列表分配是贪婪的,因此您永远不能分配给(@ours, @theirs)并期望@theirs得到任何东西。换句话说......您无法将“数组”传递给子例程。在Perl中,子程序只能接收0个或更多标量的列表。
您可以在循环内部交换数组中的各个(标量)元素,但这需要假设两个数组具有相等的长度。
for my $i (0 .. $#ours) {
    ( $ours[$i], $theirs[$i] ) = ( $theirs[$i], $ours[$i] );
} 

Perl 5.22引入了一个实验性功能,称为引用别名,允许您对引用进行赋值。如果您正在运行5.22或更高版本,则可以启用实验性功能,然后执行此操作。
(\@ours, \@theirs) = (\@theirs, \@ours);

为启用该功能并禁用使用实验性功能的警告,您应执行以下操作。
use v5.22;
use warnings;
use feature 'refaliasing';
no warnings 'experimental::refaliasing';

或者,安装实验性模块,该模块会为您处理警告。
use v5.22;
use warnings;
use experimental 'refaliasing';

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接