我必须对 Perl 脚本进行修改,这是我第一次尝试理解 Perl。我看到以下内容:
my %trades;
...
foreach my $row (@$rows) {
@{$trades{pop @$row}} = @$row;
}
我对此感到困惑,因为似乎我们正在弹出数组中的最后一项@$row
并将哈希键设置%trades
为弹出的项并将值设置为@$row
。
这种理解正确吗?
我必须对 Perl 脚本进行修改,这是我第一次尝试理解 Perl。我看到以下内容:
my %trades;
...
foreach my $row (@$rows) {
@{$trades{pop @$row}} = @$row;
}
我对此感到困惑,因为似乎我们正在弹出数组中的最后一项@$row
并将哈希键设置%trades
为弹出的项并将值设置为@$row
。
这种理解正确吗?
要理解那段代码,我们需要清楚三件事:
评估顺序:
EXPR_A = EXPR_B
先评估EXPR_B
再评估EXPR_A
。
复制语义:
@new_array = @old_array
@old_array
将over的值复制到@new_array
。
复杂数据结构的解引用:
@{ $trades{$key} }
访问散列中调用的条目$key
,%trades
并将其视为数组引用。
总之,您的代码等同于:
foreach my $row (@$rows) {
my @copy = @$row;
my $key = pop @$row;
@{ $trades{$key} } = @copy;
}
(同时保留我能看到的所有副作用)
所以例如
$rows = [
[1, 2, "keyA"],
[3, 4, "keyB"],
];
会创造
%trades = (
keyA => [1, 2, "keyA"],
keyB => [3, 4, "keyB"],
);
$rows = [
[1, 2],
[3, 4],
];
写那行的人对评估顺序有非常精确的了解,并且喜欢折磨维护程序员。
循环相当于
my %trades = map { $_->[-1] => [ @$_ ] } @$rows
除了这种方式@$rows
保持不变。IMO应该这样写。