不使用“@tmp”交换两个数组

Swap two arrays without using `@tmp`

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

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

那么,我该如何处理数组变量呢?

# (@ours, @theirs) = (@theirs, @ours);  # XXX

# lame
my @tmp = @ours;
@ours = @theirs;
@theirs = @tmp;

Perl 将所有列表展平,并且列表分配是贪婪的,因此您永远不能分配给 (@ours, @theirs) 并期望 @theirs 得到任何东西。换句话说...您不能将 'array' 传递给子例程。 Perl 中的子例程只能接收 0 个或更多标量的列表。

您可以在循环内交换数组的各个(标量)元素,但这假定两个数组的长度相等

for my $i (0 .. $#ours) {
    ( $ours[$i], $theirs[$i] ) = ( $theirs[$i], $ours[$i] );
} 

Perl 5.22 确实引入了一个名为 reference aliasing 的实验性功能,它允许您分配给一个引用。如果您是 运行 5.22 或更高版本,您可以启用实验性功能,然后执行此操作。

(\@ours, \@theirs) = (\@theirs, \@ours);

要启用该功能,并禁用使用实验性功能的警告,您可以这样做

use v5.22;
use warnings;
use feature 'refaliasing';
no warnings 'experimental::refaliasing';

或者,安装 experimental 为您处理警告的模块

use v5.22;
use warnings;
use experimental 'refaliasing';

一些逻辑呢

@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)。