perl - 我在这里缺少 $_的语义?

  显示原文与译文双语对照的内容
0 0

在分析过程中,我发现了这个功能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->( $_ ) } @_;

看起来功能与我。 我丢失了某些特殊情况的行为 $_这儿,它的较长版本金额以某种方式?

时间:原作者:1个回答

0 0

巧妙边缘情况如下: 里面 foreach回路或 map在默认的变量表达式, $_是别名 为原始值。 e .g 。

@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

别名是可传递的,因此inner $_[0]别名为 $_,别名为outer $_[0],它是不断的别名 1/ $array[0].

是干什么用的 local $_ = $_[$_]在这里做什么?

  • 它可以用来制作 副本的值,从而避免混叠了这个疯狂的行为
  • 这说明意图 来创作$_可见回调。

以确保复制语义( 从而避免意外的副作用) 此函数的设计是好的而不是特别overengineered Perl了所以感觉自然。

( note: map {local $_ = $_; ...} @_本来是足够生成副本)

原作者:
...