ubu*_*lex 6 arrays perl arguments function shift
sub foo {
$arg1 = shift @_;
$arg2 = shift @_;
# ...
}
Run Code Online (Sandbox Code Playgroud)
这个成语有什么好处?我只看到比较明确地有工作的缺点$_[0],$_[1]......阵列具有被移位,这是费时.它被破坏了,所以在稍后的时间点,参数已经消失了(如果你再次需要它们并且用不同的值覆盖你的$ arg1,那就很难过).
移位@_很常见,OO perl所以参数可以从类的实例中分离出来,它自动作为第一个元素添加@_.
在为输入参数分配默认值时,它也可以用来少写,虽然我个人觉得它不吸引人,
sub foo {
my $arg1 = shift // 2;
my $arg2 = shift // 7;
# ...
}
Run Code Online (Sandbox Code Playgroud)
与明确使用$ [0],$ 1,... 相比,我认为只有缺点
而不是使用$_[0], $_[1],@_一次分配整个数组是更好/更少的错误/更可读的实践.
my ($arg1, $arg2) = @_;
Run Code Online (Sandbox Code Playgroud)
另请注意,@_元素被别名传递给变量,因此可能会发生意外更改,
sub foo {
$_[0] = 33;
$_[1] = 44;
}
my ($x, $y) = (11,22);
print "($x, $y)\n";
foo($x, $y);
print "($x, $y)\n";
Run Code Online (Sandbox Code Playgroud)
产量
(11, 22)
(33, 44)
Run Code Online (Sandbox Code Playgroud)
$_[0]直接访问等比使用命名参数[1]更快,但是有很多理由更喜欢命名参数.
到目前为止,使用命名参数的最重要原因是作为一种文档形式.
@_直接使用很难阅读,因为很难跟踪哪个参数具有什么价值.
例如," $_[4]包含什么?是行吗?还是那样$_[5]?"
偶然使用错误的索引很容易.
@_由于符号的数量,直接使用很难阅读.
相比
grep { $_[0]{$_} =~ /.../ } keys %{$_[0]}
Run Code Online (Sandbox Code Playgroud)
同
grep { $foos->{$_} =~ /.../ } keys %$foos
Run Code Online (Sandbox Code Playgroud)它对提供默认值很有用.
sub f {
my $x = shift // "abc";
my $y = shift // "def";
...
}
Run Code Online (Sandbox Code Playgroud)复制到标量有效地引入了逐个拷贝的语义,这可能很有用.
$ perl -le'my $x=123; sub f { $x=456; print $_[0]; } f($x);'
456
$ perl -le'my $x=123; sub f { my $arg = shift; $x=456; print $arg; } f($x);'
123
Run Code Online (Sandbox Code Playgroud)笔记:
是否是我的首选
sub f {
my (...) = @_;
...
}
Run Code Online (Sandbox Code Playgroud)
要么
sub f {
my ... = shift;
my ... = shift;
...
}
Run Code Online (Sandbox Code Playgroud)我同意所有观点。但基本问题仍然存在:为什么我应该转移而不是进行列表分配或一系列标量分配?
既然我做了换档,我会解释我为什么这样做。
您可以通过三种方式处理子程序的参数:
sub foo {
my ( $user, $date, $system ) = @_; # No shifting, and @_ preserved
Run Code Online (Sandbox Code Playgroud)
sub foo {
my $user = $_[1];
my $date = $_[2]; # Must be YYYY-MM-DD
my $system = $_[3]; # Optional
Run Code Online (Sandbox Code Playgroud)
sub foo {
my $user = shift;
my $date = shift; # Must be YYYY-MM-DD
my $system = shift; # Optional
Run Code Online (Sandbox Code Playgroud)
方法1流行。Ikegami 使用它,许多其他高级 Perl 开发人员也使用它。它为您提供了一个参数列表,并为您提供了一种方式来说明这些是我的参数而不是其他参数。
但是,方法 2和方法 3为您提供了一个漂亮的、易于阅读的参数列表,您可以在行尾添加注释。不过方法2也有保持 值的优点,那@_为什么要用shift呢?
再看看方法2。看到问题了吗?我开始与@_[1]不与@_[0]- 一个常见的错误。另外,在开发子程序时,您可能决定对参数重新排序。使用方法 2意味着对它们重新编号。方法 3不需要重新编号,因此您不会以这样的方式结束:
sub foo {
my $date = $_[1]; # Must be YYYY-MM-DD
my $user = $_[0];
my $system = $_[2]; # Optional
Run Code Online (Sandbox Code Playgroud)
嗯,参数的顺序又是什么?
那么,如何保留 的价值@_呢?如果您编写一个程序来更改参数的值,则您可能不会从@_. 而且,如果你这样做,你很可能会产生一些容易出错的代码。如果你需要修改一个参数,把它放在另一个变量中并修改它。这不是 1975 年,当时计算机只有 4 KB 的内存。
而且,谈到 1970 年代,计算机的速度足够快,以至于几次(数十、数百、数千)轮班操作的时间不会对您的总运行时间产生太大影响。如果您的程序效率低下,请在效率低下的地方对其进行优化,而不是通过可能减少几毫秒来消除班次。比实际运行程序花费更多的时间来维护您的程序。
Damian Conway(Perl Best Practices的作者)推荐Method #1和Method #3。他指出方法#1是“......更简洁,它将参数放在一个水平列表中,这增强了可读性,前提是参数数量很少。 ”(重点是我的)。
Damian 谈到方法#3:“但是,当一个或多个参数必须经过完整性检查或需要用尾随注释记录时,基于班次的版本是更可取的。”
我只是一直使用方法#3。这样,如果我的参数列表增长,我不必担心重新格式化,我只是认为它看起来更好。
| 归档时间: |
|
| 查看次数: |
2889 次 |
| 最近记录: |