0

我有以下代码

    use strict;
    sub test {
       my($greeting, @names) = @_;
       my $returnString;

       foreach my $name (@names) {
           $returnString .= "$greeting, $name!\n";
       }

       return $returnString;
    }
    print &test("Hi", "Tim", "Tom", "Chris");

哪个输出

    Hi Tim! Hi Tom! Hi Chris!

我希望能够添加多个数组。我尝试修改我的代码,如下所示

       my(@greeting, @names) = @_;
       print &test("Hi", "Tim", "Hello", "Tom", "Bye", "Chris");

但是我发现这是做不到的。从我所做的阅读中,我认为我需要将参数作为参考传递。

        my($greeting, $names) = @_;
        my @names = $names; 

但我发现这只会输出 Hi Tim!

处理这种情况的最佳方法是什么?

4

4 回答 4

4

您确实需要将它们作为引用传递,sub以便将它们作为两个单独的数组而不是单个列表接收,您只是语法错误。试试这个:

my @greetings = qw( Hi Hello );
my @names = qw( Tim Tom Chris );

# Put a \ before the variable to get a reference to it
say_greetings(\@greetings, \@names);

sub say_greetings {
  my ($greeting_ref, $name_ref) = @_;

  # Put @ before an arrayref to get the array back
  my @greet = @$greeting_ref;
...
}

此外,您不应该养成在sub呼叫前加上&. 它是 Perl 4 的保留。在 Perl 5 中,它不是必需的,并且可能会产生意想不到的副作用。

于 2013-06-12T07:25:06.443 回答
3

处理这种情况的最佳方法取决于您的需要。这里有几个选项:

  1. List::MoreUtils 'natatime'(如果订单很重要)

    use List::MoreUtils 'natatime';
    
    test( 'Hi', 'Tim', 'Hi', 'Tom' );
    
    sub test {
    
        warn( "Need to provide greeting-name pairs" ), # Check for
          return if @_ % 2;                            # data completeness
    
        my $iter = natatime, 2, @_;
    
        my $string;
        while ( my ( $greet, $name ) = $iter->() ) {
    
            $string .= "$greet $name!\n";
        }
    
        return $string;
    }
    
  2. 将传递的列表视为哈希(如果顺序无关紧要):

    test( 'Hi', 'Tim', 'Hi', 'Tom' );
    
    sub test {
    
        my %set = @_;  # warnings pragma checks for
                       # data completeness during runtime
    
        return join "\n", map { "$_ $set{$_}!" } keys %set;
    }
    
  3. 将键值对作为 arrayrefs 传递(保持顺序,保证数据完整性):

    test( [ 'Hi', 'Tim' ], [ 'Hi', 'Tom' ] );
    
    sub test { join "\n", map { "@{$_}!" } @_ }
    
于 2013-06-12T07:36:08.613 回答
1

希望这可以帮助。如果问候语和名称始终按顺序排列,则以下代码有效。

use strict;

test("Hi", "Tim", "Hello", "Tom", "Bye", "Chris");

sub test
{
        my $i;
        my $len = @_;

        for ($i = 0; $i < @_; $i += 2) {
                print "$_[$i] $_[$i + 1]\n"
        }
}

输入验证未完成。检查数组长度是否为 2 的倍数会很好。

于 2013-06-12T07:22:01.967 回答
1

您不必使用引用,按原样传递列表并迭代每个第二个元素,因为问候语和名称是成对设置的。

use strict;
use warnings;

sub test {
   my @arg = @_;

   my $returnString = "";
   foreach my $i (grep { ! ($_%2) } 0 .. $#arg) {

       my ($greeting, $name) = @arg[$i, $i+1];
       $returnString .= "$greeting, $name!\n";
   }

   return $returnString;
}

print test("Hi", "Tim", "Hello", "Tom", "Bye", "Chris");    
于 2013-06-12T07:18:41.573 回答