这有效:
my $r = someSubroutine( map { ( 0 => $_ ) } @hosts)
这不起作用,给出语法错误:
my $r = someSubroutine( map { 0 => $_ } @hosts)
我认为我理解的是,地图之后的{ }
相当于一个闭包或匿名子程序。
但是如果我在正常子例程的末尾加上“value, value
”,它将返回这些值的列表。如果我对地图使用这种简洁,那就是语法错误。
答案 0 :(得分:6)
首先,这是一个非常奇怪的陈述。 map
生成的列表看起来像
0, $hosts[0], 0, $hosts[1], 0, $hosts[2], ...
所以它对于分配哈希是没用的,因为它与
相同my %hash = (0 => $hosts[-1])
map
将接受 BLOCK (这是您正在使用的)或简单的 EXPRESSION 作为其第一个参数。这里的问题是{ 0 => $_ }
看起来非常像一个带有单个元素的匿名哈希,它是一个 EXPRESSION ,这就是解析器猜测它的内容。在第二个参数之前, EXPRESSION 需要一个逗号,但是当perl到达map { 0 => $_ } @hosts
中的右括号时,它找不到一个,因此它必须抛出语法错误,因为它太远而无法回到开口支撑并假设一个阻挡
{
启动散列引用和块,因此map { ...
可以是映射BLOCK LIST的开头或映射EXPR,LIST。因为Perl没有预测结束}
,所以它必须根据它在{
之后发现的内容来猜测它正在处理什么。通常情况下它是正确的,但如果它没有,它将不会意识到出现问题,直到它到达}
并遇到丢失(或意外)的逗号。语法错误将在}
附近报告,但您需要更改{
附近的内容,例如使用一元+
或分号为Perl提供一些帮助
解决方案是在您发现时消除歧义。其中任何一个都可以使用
map +( 0 => $_ ), @hosts
map(( 0 => $_ ), @hosts)
map { +0 => $_ } @hosts
map { ( 0 => $_ ) } @hosts
map { ; 0 => $_ } @hosts
答案 1 :(得分:4)
map
有两种语法:
map BLOCK LIST e.g. map { f() } g()
map EXPR, LIST e.g. map f(), g()
当Perl遇到map
时,需要确定使用了哪种语法。假设map
之后的第一个令牌是{
。这是BLOCK的开始,对吧?坚持,稍等!表达式也可以从{
开始!
my $hash_ref = { key => 'val' };
语法含糊不清。 Perl必须“猜测”您正在使用哪种语法。 Perl展望下一个令牌以帮助猜测,但有时它仍然猜错了。这是其中一种情况。
以下是此标准的解决方法:
map {; ... } LIST # Force Perl to recognize the curly as the start of a BLOCK
map +{ ... }, LIST # Force Perl to recognize the curly as the start of a hash constructor
;
不能成为哈希构造函数的一部分,因此{
只能启动BLOCK。+
必须启动EXPR(而不是BLOCK)。这是一个在这种情况下无助于帮助的运营商。例如,
map {; +{ $row->{id} => $row->{val} } } @rows
答案 2 :(得分:1)
map
:http://perldoc.perl.org/functions/map.html
简而言之,你应该使用像parens或+
这样的小助手 - 符号,这样perl就能正确解析{...}
构造:
my $r = someSubroutine( map { + 0 => $_ } @hosts)