%$var是否取消引用Perl哈希?

%$var是否取消引用Perl哈希?,perl,reference,Perl,Reference,我向一个子例程发送一个散列,并使用my($arg\u ref)=@ 但是,%$arg\u ref到底是什么?%$是否取消对散列的引用?$arg\u ref是一个标量,因为它使用了$符号。据推测,它包含一个散列引用。因此,是的,%$arg\u ref遵从该散列引用。另一种编写方法是%{$arg\u ref}。这使得代码的意图更加清晰,尽管更加冗长 引用perldata(1): 你的例子是: %$arg_ref # hash dereferenced from the

我向一个子例程发送一个散列,并使用
my($arg\u ref)=@


但是,
%$arg\u ref
到底是什么?
%$
是否取消对散列的引用?

$arg\u ref
是一个标量,因为它使用了
$
符号。据推测,它包含一个散列引用。因此,是的,
%$arg\u ref
遵从该散列引用。另一种编写方法是
%{$arg\u ref}
。这使得代码的意图更加清晰,尽管更加冗长

引用perldata(1)

你的例子是:

     %$arg_ref           # hash dereferenced from the value "arg_ref"
my($arg\u ref)=@
获取函数参数堆栈中的第一项,并将其放置在名为
$arg\u ref
的局部变量中。调用方负责传递散列引用。一种更规范的写作方式是:

my $arg_ref = shift;
要创建哈希引用,可以从哈希开始:

some_sub(\%hash);
或者,您可以使用匿名哈希引用创建它:

some_sub({pi => 3.14, C => 4}); # Pi is a gross approximation.

不必像那样取消对整个散列的引用,您可以使用

$arg_ref->{key}

Perl中引用(创建和使用它们)的一个很好的简要介绍是
perldoc perfeftut
。您也可以(或以pdf格式获取)。(它更多地讨论复杂数据结构中的引用,而不是子例程的传入和传出,但语法是相同的。)

由于有点清楚,此构造用于提供哈希引用,作为子例程的命名参数列表,因此还应注意

sub foo {
  my ($arg_ref) = @_;
  # do something with $arg_ref->{keys}
}
可能是过度杀伤力,而不是仅仅打开包装@_

sub bar {
  my ($a, $b, $c) = @_;
  return $c / ( $a * $b );
}
取决于参数列表的复杂程度

my %hash = ( fred => 'wilma',
             barney => 'betty');
my $hashref = \%hash;
my $freds_wife = $hashref->{fred};
my %hash_copy = %$hash # or %{$hash} as noted above.
Soo,语法灵活性有什么意义?让我们试试这个:

my %flintstones = ( fred => { wife => 'wilma',
                              kids => ['pebbles'],
                              pets => ['dino'],
                            }
                    barney => { # etc ... }
                  );
实际上,对于这样的深层数据结构,从ref开始通常更方便:

my $flintstones = { fred => { wife => 'Wilma',
                               kids => ['Pebbles'],
                               pets => ['Dino'],
                              },
                   };
好了,弗雷德得到了一只新宠物“Velociraptor”

push @{$flintstones->{fred}->{pets}}, 'Velociraptor';
弗雷德有多少宠物

标量@flintstones->{fred}->{pets}

让我们喂他们

for my $pet ( @ {flintstones->{fred}->{pets} } ) {
    feed($pet)
}

等等。花括号的汤一开始看起来有点吓人,但最终处理它们变得相当容易,只要处理它们的方式是一致的。

原型设计可以用来消除调用方传递引用的责任。我不认为教新的Perl程序员原型设计是一个好主意。这是一个来自C和Pascal的巨大障碍。在原型对我有任何意义之前,我需要了解传递列表的真正价值。然而,$sigil并不意味着一个标量变量。它表示标量值,如$hash{key}和$array[$num]。在本例中,它是一个标量变量,因为它是一个标量值,后面没有索引字符。我想我没有说过$表示任何类型的变量。但我还是继续引用了perldata的话,这引出了$sigil的含义。避开!逃走不仅很难使用和加载陷阱,而且当用户真正传递例程可能修改的引用时,他们会认为他们正在将副本传递给子例程。
for my $pet ( @ {flintstones->{fred}->{pets} } ) {
    feed($pet)
}