在perl中,使用默认参数调用多个子程序是不好的做法?
我正在学习perl,并了解,使用shift打开子例程参数是一个常见且被接受的做法。我也明白,省略函数参数以使用默认的@_数组是常见且可接受的做法。
考虑到这两件事情,如果你调用一个没有参数的子程序,那么@_可以(如果使用shift)就会被改变。这是否意味着使用默认参数调用另一个子例程,或者实际上使用@_数组后,被认为是不好的做法?考虑这个例子: sub total { # calculate sum of all arguments my $running_sum; # take arguments one by one and sum them together while (@_) { $running_sum += shift; } $running_sum; } sub avg { calculate the mean of given arguments if (@_ == 0) { return } my $sum = &total; # gets the correct answer,but changes @_ $sum / @_ # causes division by zero,since @_ is now empty } 我的直觉感觉告诉我,使用转换解压缩参数实际上是不好的做法,除非你的子例程实际上应该改变传递的参数,但是我已经在多个地方阅读过,包括Stack Overflow,这不是一个糟糕的做法。 所以问题是:如果使用shift是普遍的做法,我应该总是假设传递的参数列表可能会被改变,作为子例程的副作用(如引用的例子中的& total子例程)?有没有办法通过值来传递参数,所以我可以确定参数列表没有改变,所以我可以再次使用它(例如引用的文本中的& avg子例程)? 解决方法
一般来说,从参数转换是可以的 – 使用& sigil调用函数不是。 (除了在某些非常具体的情况下,你可能永远不会遇到。)
你的代码可以被重写,所以总数不会从@_转移。使用for循环甚至可以更有效率。 sub total { my $total = 0; $total += $_ for @_; $total; } 或者您可以使用List :: Util中的sum函数: use List::Util qw(sum); sub avg { @_ ? sum(@_) / @_ : 0 } 使用shift不是常见的,除了在面向对象的Perl中提取$ self。但是,当你总是称之为foo(…)的函数时,如果foo移动或者不移动参数数组,这并不重要。 即使您无法更改总计的实现,也可以使用明确的参数列表调用该子类,因为参数列表是数组的副本: (a)& total – 呼叫总数与相同的@_,并覆盖原型。 表格(b)是标准的。不应该看到格式(c),除非在同一个包装中的sub的很少的情况下,sub具有原型(并且不使用原型),并且由于某些模糊的原因而必须被覆盖。证明设计不佳。形式(a)仅适用于尾部呼叫(@_ =(…); goto& foo)或其他形式的优化(并且过早优化是所有邪恶的根源)。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |