gpt4 book ai didi

perl - 我在这里错过了 $_ 的一些语义吗?

转载 作者:行者123 更新时间:2023-12-04 00:58:41 25 4
gpt4 key购买 nike

在分析过程中,我在 List::UtilsBy 中遇到了这个函数。 :

sub rev_nsort_by(&@) {
my $keygen = shift;
my @keys = map { local $_ = $_[$_]; scalar $keygen->( $_ ) } 0 .. $#_;
return map { $_[$_] } sort { $keys[$b] <=> $keys[$a] } 0 .. $#_;
}

rev_nsort_by 根据一些关键谓词进行反向数字排序,例如:
my @objects = load_objects_from_database();
# sort by rating, highest first
@objects = rev_nsort_by { $_->rating } @objects;

我完全理解为什么 rev_nsort_by ,如上所示,按预期工作,但我想知道为什么它如此复杂。具体来说,我想知道为什么
my @keys = map { local $_ = $_[$_]; scalar $keygen->( $_ ) } 0 .. $#_;

没有写成
my @keys = map { scalar $keygen->( $_ ) } @_;

这看起来在功能上与我相同。我是否错过了 $_ 的一些极端行为?在这里,哪个较长的版本在某种程度上相当于?

最佳答案

这里有一个微妙的边缘情况:Inside foreach循环,或 map表达式,默认变量 $_别名为原始值。例如

@nums = 1..5;
@foo = map { $_ *= 2 } @nums;
# both @foo and @nums contain 2, 4, 6, 8, 10 now.

然而,常量不是有效的左值,所以我们不能这样做
@foo = map { $_ *= 2 } 1, 2, 3, 4, 5;
# Modification of read-only value
@_数组也是原始值的别名,因此请想象以下边缘情况:
sub buggy (&@) { my $cb = shift; map $cb->($_), @_ };

buggy { $_ *= 2 } 1, 2, 3; # Modification of read-only value attempted
buggy { $_[0] *= 2} 1, 2, 3; # ditto

my @array = 1 .. 5;
buggy { $_ *= 2 } @array; # @array now is 2, 4, 6, 8, 10
buggy { $_[0] *= 2 } @array; # ditto

别名是可传递的,所以内部 $_[0]别名为 $_ ,别名为外部 $_[0] ,这是常量 1 的别名/ $array[0] .

那么, local $_ = $_[$_] 是什么意思?在这里做什么?
  • 它复制了值,从而避免了这种疯狂的别名行为
  • 它显示了制作 $_ 的意图回调可见。

  • 确保复制语义(从而避免意外的副作用)对 Perl 来说感觉很自然,因此该功能设计良好,并没有特别过度设计。

    (注意: map {local $_ = $_; ...} @_ 足以制作副本)

    关于perl - 我在这里错过了 $_ 的一些语义吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16316514/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com