【问题标题】:"Passing arguments to subroutine"-question?“将参数传递给子程序”-问题?
【发布时间】:2010-11-25 09:27:46
【问题描述】:

routine2 也可以,还是我不应该这样做? (我不需要子程序中的@list 副本)

#!/usr/bin/perl
use 5.012;
use warnings;
my @list = 0 .. 9;


sub routine1 {
    my $list = shift;
    for (@$list) { $_++ };
    return $list
}
my $l = routine1( \@list );
say "@$l";


sub routine2 {
    for (@list) { $_++ };
}
routine2();
say "@list";

【问题讨论】:

    标签: perl reference argument-passing subroutine


    【解决方案1】:

    如果它适合你,那也没关系。但是第一个 sub 可以为您传递给它的任何数组完成这项工作,这使得它更通用。

    附:请记住,@_ 包含传递给函数的参数的别名。所以你也可以使用这个:

    sub increment { $_++ for @_ }
    increment(@list);
    

    【讨论】:

    • +1 但我的回答((\@) 的原型)也可能有用(例如,如果函数稍后必须采用更多参数)。
    • @sid_com:这个子程序是你的性能瓶颈吗?过早的优化是万恶之源;)
    • 更多的是组合:它不是常用的方式,也不比常用的方式更快。
    【解决方案2】:

    如果您担心语法看起来不错,试试这个:

    sub routine3 (\@) {
      for (@{$_[0]}) { $_++ }
    }
    
    my @list = (0 .. 9);
    routine3(@list);
    say "@list"; # prints 1 .. 10
    

    这使用原型声明routine3 - 它通过引用获取数组参数。所以$_[0] 是对@list 的引用,而不是调用者需要的难看的\。 (有些人不鼓励原型,所以请随意使用。我喜欢它们。)

    但除非这是对您的实际日常工作的简化,否则我会这样做:

    my @list = 0 .. 9;
    my @new_list = map { $_ + 1 } @list;
    say "@new_list";
    

    除非routine 实际上真的很复杂,并且以某种方式修改原始数组至关重要,否则我只会使用map。尤其是map,你可以插入一个子程序:

    sub complex_operation { ... }
    
    my @new_list = map { complex_operation($_) } @list;
    

    当然,您可以使用(_)complex_operation 进行原型设计,然后编写map(complex_operation, @list);,但我个人喜欢括号语法。

    【讨论】:

    • 我不需要原型,我的例子是简化的。
    • @sid_com - 如果您已经知道自己需要做什么和不需要做什么,为什么还要问我们?如果您使用选项 1,我将使用原型并使调用代码看起来更好,只是作为个人喜好,但否则我相信它们是相同的代码。 (尽管由于您正在修改数组,因此您实际上并不需要返回它。)
    • 制作“不喜欢原型”的情况:请注意,这种方法需要您将恰好一个数组(而不是任意列表)传递给子。例如,原型会阻止您执行routine3($foo, $bar, $baz)routine3(@first, @second)。相反,您必须创建一个临时数组,将所有值放入其中,传递它,然后将结果返回给原始变量:my @temp = ($foo, $bar, $baz); routine3(@temp); ($foo, $bar, $baz) = @temp;
    • 当通过引用传递时,“\@array”并没有给我带来太多困扰,它更多的是子程序中的取消引用——它可能更频繁,我必须考虑更多。
    • @sid_com - 我总是喜欢在调用代码时使用干净的语法,因为我们创建函数来调用它们而不是查看它们的内部代码,所以我通常不在乎什么可怕的语法在他们里面。但我明白你为什么不喜欢所有的取消引用。
    猜你喜欢
    • 2023-03-03
    • 1970-01-01
    • 2016-07-02
    • 2019-01-18
    • 2019-06-05
    • 2018-04-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多