将两个或多个数组传递给Perl子例程

| 我在传递和读取子例程中的参数时遇到麻烦,该子例程应该有两个数组。
sub two_array_sum { # two_array_sum ( (1 2 3 4), (2, 4, 0, 1) ) -> (3, 6, 3, 5)
  # I would like to use parameters @a and @b as simply as possible
}

# I would like to call two_array_sum here and pass two arrays, @c and @d
我已经从网上看到并尝试了几个示例,但是没有一个对我有用。     
已邀请:
有两种方法可以执行此操作: 通过原型 引用 但是在我讨论这些之前-如果您在问题中显示的是关于您想做什么的程度-让我建议
List::MoreUtils::pairwise
因此,您将在哪里编写此代码:
my @sum = two_array_sum( @a, @b )
您只需编写以下代码:
my @sum = pairwise { $a + $b } @a, @b;
通过原型 类似于
push
。 (就像
push
一样,它要求在某物上贴
@
sub two_array_sub (\\@\\@) { 
    my ( $aref, $bref ) = @_;
    ...
}
这样你做的时候
two_array_sub( @a, @b );
有用。通常情况下,它只会以一长串的形式显示在您的子目录中。正如您在下面的讨论中所看到的,它们并不适合所有人。 引用 这就是每个人向您展示的方式。
some_sub( \\@a, \\@b );
关于原型 他们很挑剔。如果您有裁判,这将不起作用:
two_array_sub( $arr_ref, $brr_ref );
您必须像这样通过它们:
two_array_sub( @$arr_ref, @$brr_ref );
但是,由于嵌套数组很深,使“数组表达式”变得非常丑陋,因此我经常避免Perl的麻烦,因为您可以通过将Perl放在类型为“ character class”的结构中来重载Perl将使用的引用类型。 。
\\[$@]
表示引用可以是标量或数组。
sub new_two_array_sub (\\[$@]\\[$@]) { 
    my $ref = shift;
    my $arr = ref( $ref ) eq \'ARRAY\' ? $ref : $$ref; # ref -> \'REF\';
    $ref    = shift;
    my $brr = ref( $ref ) eq \'ARRAY\' ? $ref : $$ref;
    ...
}
因此,所有这些工作:
new_two_array_sub( @a, $self->{a_level}{an_array} );
new_two_array_sub( $arr, @b );
new_two_array_sub( @a, @b );
new_two_array_sub( $arr, $self->{a_level}{an_array} );
但是,由于某些原因,Perl对此还是很挑剔的:
new_two_array_sub( \\@a, $b );
OR 
new_two_array_sub( $a, [ 1..3 ] );
或仍然可以视为对数组的引用的任何其他“构造函数”。幸运的是,您可以使用旧的Perl 4
&
关闭Perl。
&new_two_array_sub( \\@a, [ 1..3 ] );
然后,子程序中的复用代码负责处理两个数组引用。     
将对数组的引用传递给函数:
two_array_sum( \\@a, \\@b )
请勿使用
a
b
作为变量名,因为
$a
$b
是特殊的(用于排序)。     
我引用23英镑的报价,但您应该阅读全部内容:
   Making References

   References can be created in several ways.

   1.  By using the backslash operator on a variable, subroutine, or
       value.  (This works much like the & (address-of) operator in C.)
       This typically creates another reference to a variable, because
       there\'s already a reference to the variable in the symbol table.
       But the symbol table reference might go away, and you\'ll still have
       the reference that the backslash returned.  Here are some examples:

           $scalarref = \\$foo;
           $arrayref  = \\@ARGV;
           $hashref   = \\%ENV;
           $coderef   = \\&handler;
           $globref   = \\*foo;
...
   Using References

   That\'s it for creating references.  By now you\'re probably dying to
   know how to use references to get back to your long-lost data.  There
   are several basic methods.

   1.  Anywhere you\'d put an identifier (or chain of identifiers) as part
       of a variable or subroutine name, you can replace the identifier
       with a simple scalar variable containing a reference of the correct
       type:

           $bar = $$scalarref;
           push(@$arrayref, $filename);
           $$arrayref[0] = \"January\";
           $$hashref{\"KEY\"} = \"VALUE\";
           &$coderef(1,2,3);
           print $globref \"output\\n\";
    
my @sums = two_array_sum(\\@aArray, \\@bArray);

sub two_array_sum { # two_array_sum ( (1 2 3 4), (2, 4, 0, 1) ) -> (3, 6, 3, 5)
    my ($aRef, $bRef) = @_;
    my @result = ();

    my $idx = 0;
    foreach my $aItem (@{$aRef}) {
        my $bItem = $bRef->[$idx++];
        push (@result, $aItem + $bItem);
    }

    return @result;
}
    
您需要使用引用将数组或哈希传递给子例程,例如:
sub two_array_sum {
  my ($x, $y) = @_;
  #process $x, $y;
}
two_array_sum(\\@a, \\@b);
    
您不能将数组传递给函数。函数只能接受标量列表作为参数。因此,您需要传递标量,该标量提供足够的数据来重新创建阵列。 最简单的方法是将引用传递给数组。
sub two_array_sum {
   my ($array0, $array1) = @_;

   my @array0 = @$array0;
   my @array1 = @$array1;

   return map { $array0[$_] + $array1[$_] } 0..$#array0;
}
您甚至可以避免重建数组并直接使用引用。
sub two_array_sum {
   my ($array0, $array1) = @_;
   return map { $array0->[$_] + $array1->[$_] } 0..$#$array0;
}
用法:
my @array0 = (1, 2, 3, 4);
my @array1 = (2, 4, 0, 1);
two_array_sum(\\@array0, \\@array1);
方括号构造一个匿名数组(由其中的表达式结果填充),并返回对该数组的引用。因此,以上内容也可以编写如下:
two_array_sum([1, 2, 3, 4], [2, 4, 0, 1]);
    
这些方法是规范的。另一种方法是:
use strict;
my $data;

@{$data->{array1}} = qw(foo bar baz);
@{$data->{array2}} = qw(works for me);
testsub($data);

sub testsub
{
    my ($data) = @_;
    print join \"\\t\", @{$data->{array1}}, \"\\n\";
    print join \"\\t\", @{$data->{array2}}, \"\\n\";
    $data->{array1}[3] = \"newitem\";
    delete $data->{array2};
    push @{$data->{newarray}}, (1, 2, 3);
    return $data;
}
当您以这种方式进行操作时,可以对变量进行更严格的控制,而不会遇到程序信息与配置信息混杂在一起的情况。 通常,在任何程序中,我的变量都不会超过三个或四个。 我还对它保持一个系统-我使用列表哈希值列表对象的哈希值。
$config->{server}[0]{prod}[0]{input}[0] = \'inputfile\';
原因是,只要我坚持交替使用每种方法,“ 34”都可以转储整个结构-而且我可以更好地控制数据范围,并且可以轻松地传递整个结构。 我经常发现自己将这样的多个结构传递给子例程。作为标量,它们通过得很好,谢谢。     

要回复问题请先登录注册