我必须对Perl脚本进行修改,这是我第一次尝试理解Perl。我看到以下内容:
my %trades;
...
foreach my $row (@$rows) {
@{$trades{pop @$row}} = @$row;
}
我对此感到困惑,因为看起来我们正在弹出数组@$row
中的最后一项,并将%trades
的哈希键设置为弹出的项并设置值成为@$row
。
这种理解是否正确?
答案 0 :(得分:26)
要理解这段代码,我们需要清楚三件事:
评估顺序:
EXPR_A = EXPR_B
在评估EXPR_B
之前评估EXPR_A
。
复制语义:
@new_array = @old_array
将@old_array
的值复制到@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],
];
撰写该专栏的人对评估顺序非常准确,并且喜欢折磨维护程序员。
答案 1 :(得分:3)
循环等同于
my %trades = map { $_->[-1] => [ @$_ ] } @$rows
除了这种方式@$rows
保持不变。 IMO应该这样写。