如何将哈希传递给Perl中的函数?

rlb*_*ond 38 perl declaration function parameter-passing

我有一个带变量和关联数组的函数,但我似乎无法让它们正确传递.我认为这与函数声明有关,但是我无法弄清楚它们在Perl中是如何工作的.对此有一个很好的参考,我如何实现我的需求?

我应该补充一点,它需要通过引用传递.

sub PrintAA
{
    my $test = shift;
    my %aa   = shift;
    print $test . "\n";
    foreach (keys %aa)
    {
        print $_ . " : " . $aa{$_} . "\n";
        $aa{$_} = $aa{$_} . "+";
    }
}
Run Code Online (Sandbox Code Playgroud)

Pau*_*lin 67

传递引用而不是散列本身.如在

PrintAA("abc", \%fooHash);

sub PrintAA
{
  my $test = shift;
  my $aaRef = shift;

  print $test, "\n";
  foreach (keys %{$aaRef})
  {
    print $_, " : ", $aaRef->{$_}, "\n";
  }
}
Run Code Online (Sandbox Code Playgroud)

另请参见perlfaq7:如何传递/返回{Function,FileHandle,Array,Hash,Method,Regex}?


Jon*_*ler 16

此代码有效:

#!/bin/perl -w

use strict;

sub PrintAA
{
    my($test, %aa) = @_;
    print $test . "\n";
    foreach (keys %aa)
    {
        print $_ . " : " . $aa{$_} . "\n";
    }
}

my(%hash) = ( 'aaa' => 1, 'bbb' => 'balls', 'ccc' => \&PrintAA );

PrintAA("test", %hash);
Run Code Online (Sandbox Code Playgroud)

关键点是在函数的my()'statement'中使用数组上下文.


阵列上下文业务实际上做了什么?

简而言之,它使它正常工作.

这意味着@_分配参数数组中的第一个值$test,并将其余项分配给散列%aa.鉴于我调用它的方式,其中有一个奇数个项目@_,因此一旦分配了第一个项目,就可以分配$test偶数个%aa项目,每个项目的第一个项目是关键(' aaa','bbb','ccc'在我的例子中),第二个是相应的值.

有可能替换%aa@aa,在这种情况下,阵列中将有6个项目.也可以替换%aa$aa,并且在这种情况下,变量$aa将包含值'aaa',并且@_赋值将忽略其余的值.

如果省略变量列表周围的括号,Perl拒绝编译代码.其中一个替代答案显示了符号:

my $test = shift;
my(%aa) = @_;
Run Code Online (Sandbox Code Playgroud)

这几乎与我写的相同; 不同之处在于,在两个my语句之后,@_此变体中仅包含6个元素,而在单个my版本中,它仍包含7个元素.

关于数组上下文,在SO中肯定存在其他问题.


其实,我不是问有关my($test, %aa) = @_;我问my(%hash) = ( 'aaa' => 1, 'bbb' => 'balls', 'ccc' => \&PrintAA );my %hash = { 'aaa' => 1, ... };

不同之处在于{...}表示法生成散列引用,而(...)表示法生成一个列表,该列表映射到散列(而不是散列引用).同样,[...]生成数组引用而不是数组.

实际上,更改"主要"代码使其显示为:my(%hash)= {...}; 并且你得到一个运行时(但不是编译时)错误 - 谨慎处理行号,因为我已经在我的文件中添加了替代编码:

Reference found where even-sized list expected at xx.pl line 18.
...
Use of uninitialized value in concatenation (.) or string at xx.pl line 13.
Run Code Online (Sandbox Code Playgroud)

  • 请记住,如果数组很大,引用效率会更高.这种调用样式将所有数组元素推送到堆栈上,并将它们全部弹出.无论数组大小如何,引用都是单个元素. (3认同)
  • TMTOWTDI,但我更喜欢这种方法. (2认同)

cha*_*aos 12

或者:

sub PrintAA
{
    my $test       = shift;
    my %aa         = @_;
        print $test . "\n";
        foreach (keys %aa)
        {
                print $_ . " : " . $aa{$_} . "\n";
                $aa{$_} = $aa{$_} . "+";
        }
}
Run Code Online (Sandbox Code Playgroud)

你从根本上缺少的是关联数组不是单个参数(尽管关联数组引用是,如Paul Tomblin的答案).