Perl 为什么要映射的参数之间不需要逗号?

Perl 为什么要映射的参数之间不需要逗号?,perl,higher-order-functions,Perl,Higher Order Functions,为什么以下是有效的 my @ys = map { $_ * $_ } @xs; 下面的句子无效吗 my @ys = map { $_ * $_ }, @xs; map是一种语言构造,而不是真正的函数,还是块有特殊的规则?是的,map是一种语言构造 比如说: 示例中的块只是一个简单的表达式,因此这两个语句是等效的: my @ys = map { $_ * $_ } @xs; my @ys = map $_ * $_, @xs; map是列表运算符和核心函数。这是一种简单的Perl语法,它不希

为什么以下是有效的

my @ys = map { $_ * $_ } @xs;
下面的句子无效吗

my @ys = map { $_ * $_ }, @xs;

map
是一种语言构造,而不是真正的函数,还是块有特殊的规则?

是的,
map
是一种语言构造

比如说:

示例中的
只是一个简单的表达式,因此这两个语句是等效的:

my @ys = map { $_ * $_ } @xs;
my @ys = map $_ * $_, @xs;
map
是列表运算符和核心函数。这是一种简单的Perl语法,它不希望子例程的块参数后面有逗号。
map
的特殊之处在于它也可以采用
map EXPR,LIST
的形式。如果将其与标准子例程一起使用,
EXPR
将作为第一个参数进行计算和传递

块参数对所有子例程都有效,如果将原型应用于子例程定义,则可以使用块参数。例如,您可以通过编写

use strict;
use warnings;
use 5.010;

sub mymap(&@) {
  use Data::Dump;
  my $sub = shift;
  my @newlist;
  push @newlist, $sub->($_) for @_;
  @newlist;
}

say for mymap { $_ * $_ } 1, 2, 3;
输出

1
4
9

但一般来说,除非你确切知道自己在做什么,否则你应该避免使用原型。通常有更好的方法来编写代码。

它是一个运算符,每个运算符定义自己的语法。Perl提供了一些工具,子例程也可以这样做


第一行是:

本节中的函数可以用作表达式中的术语。它们分为两大类:列表运算符和命名一元运算符

因此,虽然
map
不是C意义上的函数(在Perl中称为子例程),但根据Perl的定义,它是一个函数

所以
map
是一个操作符。许多运算符都有不同于子程序调用的子程序:

  • substr
    (后面必须跟1到4个逗号分隔的表达式)
  • 时间
    (无法提供参数列表)
  • 地图块列表
  • 打印阻止列表
  • 删除散列元素
  • 推送阵列,列表
  • lc
    (其中提供了调用范围的
    $\uuu
  • EXPR+EXPR
子例程可以使用原型(例如
sub-mypush(\@)
)和Devel::CallParser(例如)匹配或近似命名运算符的语法。

在这些情况下,“为什么”是“因为Larry决定这样做”。)
1
4
9