Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Perl中的参数传递样式_Perl_Parameters - Fatal编程技术网

Perl中的参数传递样式

Perl中的参数传递样式,perl,parameters,Perl,Parameters,我看到人们使用两种样式在Perl中传递命名参数: use strict; use warnings; use Data::Dumper; sub foo { print Dumper @_; } sub bar { print Dumper @_; } foo( A => 'a', B => 'b' ); bar( { A => 'a', B => 'b' } ); 使用foo()样式而不是bar()样式有什么好处?首先,对这两种方法进行说明: s

我看到人们使用两种样式在Perl中传递命名参数:

use strict;
use warnings;
use Data::Dumper;

sub foo {
    print Dumper @_;
}

sub bar {
    print Dumper @_;
}

foo( A => 'a', B => 'b' );
bar( { A => 'a', B => 'b' } );

使用foo()样式而不是bar()样式有什么好处?

首先,对这两种方法进行说明:

sub foo {
    # Transform the array to a hash
    my %args = @_;

    foreach my $key ( keys %args ) {
        print "$key => $args{$key}\n";
    }
}

# Pass an array of values
foo( A=>'a', B=>'b' );
在第一种情况下,您所做的只是传递一个数组。此上下文中的
=>
不是您可能认为的哈希键/值指示符。在这种情况下,它只是一个“胖逗号”

在第二种情况下,您将创建一个匿名散列,并将对该散列的引用作为参数传递给函数


为什么选择一个而不是另一个?在《Perl最佳实践》一书第9章“命名参数”标题下,作者建议在函数有三个以上参数时使用第二种样式。他也更喜欢它,因为它在编译时而不是在运行时捕获数量不匹配的参数

第二个方法传递对hash的引用,而第一个方法只传递一个列表

这里有两个方面:理论上,对hash的引用在性能方面可能更好,尽管对于简短的参数列表来说,这是可以忽略的。对于像
foo(a=>1,b=>2)
这样的简单调用,没有性能差异,因为
@
实际上是原始值的别名

但是,如果调用方已经在散列中包含了值,则第一种样式需要从散列转换为列表,然后再转换回散列,这可能会很慢

第二个方面是谁负责转换为散列的问题。第一种样式将它保留在被调用的函数中,如果这只是
my%args=@
,那么如果参数列表的长度不是偶数,它将产生奇怪的警告

这就是为什么我稍微喜欢第二种样式(或者我使用Perl 6,它本机支持命名参数)。

foo(a=>1,b=>2)样式是模拟命名参数的常用方式。
条({a=>1,b=>2})
通常仅用于补充(可能是可选)参数

对于典型用法,我更喜欢第一种形式。
{}
是额外的键入、额外的读取噪音,如果省略其中一个或两个大括号,则可能会产生错误。任何性能差异都可以忽略不计。另一方面,将参数包装在匿名哈希构造函数中可以帮助您在编译时而不是运行时查找错误

第二种形式通常与位置参数混合使用。e、 g.Benchmark是否做到了这一点:

cmpthese(10000, {
    foo => \&foo,
    bar => \&bar,
});
Tk将
{}
保留在外:

my $text = $w->Scrolled('Text', -width => 80, -height => 50);

这通常是一种风格上的选择。

我已经有一段时间没有读过它了,但我认为建议使用带有3+个参数的hashref,而不是标准的未命名参数列表,即调用
foo('a','b')
,而不是建议使用hashrefhashes@plusplus:本节的标题为:“对任何具有三个以上参数的子例程使用命名参数的散列。”在文章的正文中,他特别提到对转换为散列的原始名称/值对使用散列引用。这些“性能方面”是不必要的微优化,不会产生任何实际好处。散列可以像列表一样轻松使用:
foo(%hash)
或hashref:
foo(%{$hashref})
。坚持foo风格会给用户留下更多的权力。事实上,我自己的基准测试已经显示(在多个安装上)传递列表比返回引用要快——尽管返回引用似乎要快。警告比可疑的性能声明更好,但如果在运行时生成一部分参数,实际上并不能保护您所有的人。
my $text = $w->Scrolled('Text', -width => 80, -height => 50);