AFAIK,perl中的括号用于:
所以,
my $r = ($x+$y) * $z;
my(@l) = (1,2,3);
函数调用中括号的含义是什么?我没有找到任何,sub会得到一个简单的参数列表。
#!/usr/bin/env perl
use Modern::Perl;
use Data::Dumper;
sub xxx { say Dumper \@_ }
xxx( 1, 2, 3 );
xxx( 1, (2, 3) );
xxx 1, (2, 3) ;
xxx 1, 2, 3;
正确?
要求,因为perl -MO=Deparse
没有从函数调用中删除括号。
所以下一个短剧
use Moose;
has 'arg' => (is=>'rw', isa=>'Str');
返回
has('arg', ('is', 'rw', 'isa', 'Str'));
而不是简单的
has('arg', 'is', 'rw', 'isa', 'Str');
这有什么不同吗?
答案 0 :(得分:3)
在你的例子中,“它们都是相同的”的例外情况将是这样的:
xxx (1,2), 3;
以下区别:
has('arg', ('is', 'rw', 'isa', 'Str'));
has('arg', 'is', 'rw', 'isa', 'Str');
是前者构建一个列表,然后构建第二个列表,将第一个列表推送到它上面。后者将所有内容构建为单个列表。您可以使用B :: Concise看到差异;他们编译成略有不同的操作树。前一个例子的运行速度会稍微慢一点,但它的差别不大。
use strict;
use warnings;
use Benchmark qw(cmpthese);
cmpthese(-5, {
once => q[ my @x = (foo => (bar => 1, baz => 2)) ],
twice => q[ my @x = (foo => bar => 1, baz => 2 ) ],
});
__END__
Rate twice once
twice 216835/s -- -1%
once 218228/s 1% --
答案 1 :(得分:1)
当没有通过去除方法去除parens时,这是因为它们可用于确定优先级。代码段has('arg', 'is', 'rw', 'isa', 'Str')
和has('arg', ('is', 'rw', 'isa', 'Str'))
生成不同的操作码(尽管在这种情况下可以安全地删除差异)。
Parens不会创建列表。 Perl中的“列表”不是不同的数据结构。它们只是堆栈段的更易于理解的描述。如果有什么东西会创建一个列表,那么它就是列表上下文中的逗号运算符,
。 (但它没有列表)。
如果您正在调用的子例程在解析时已知,则函数调用的parens是可选的,即语法为any_function(@args)
或known_function @args
。已知函数也可以使用 prototypes 来更改参数的解析方式(无论是否使用了parens)。对于已知函数,解除的调用是否使用parens无关:两者都产生相同的操作码。