需要帮助找出如何做到这一点。我的代码:
my %hash;
$hash{'1'}= {'Make' => 'Toyota','Color' => 'Red',};
$hash{'2'}= {'Make' => 'Ford','Color' => 'Blue',};
$hash{'3'}= {'Make' => 'Honda','Color' => 'Yellow',};
&printInfo(%hash);
sub printInfo{
my (%hash) = %_;
foreach my $key (keys %_{
my $a = $_{$key}{'Make'};
my $b = $_{$key}{'Color'};
print "$a $b\n";
}
}
答案 0 :(得分:33)
简单的方法,可能会在代码发展时导致问题,只需将默认数组@_(包含所有键值对作为偶数列表)分配给%hash,然后根据其重建。所以你的代码看起来像这样:
sub printInfo {
my %hash = @_;
...
}
更好的方法是将哈希作为对子例程的引用传递。这样,您仍然可以将更多参数传递给子例程。
printInfo(\%hash);
sub PrintInfo {
my %hash = %{$_[0]};
...
}
可以在perlreftut
中找到在Perl中使用引用的简介答案 1 :(得分:8)
你非常非常接近。传递哈希值没有%_
,必须在@_
中传递。幸运的是,Hashes是使用列表上下文分配的,所以
sub printInfo {
my %hash = @_;
...
}
会让它发挥作用!
另请注意,在大多数情况下,使用子程序调用前面的&
至少不需要Perl 5.000。这些天你可以像其他语言一样调用Perl子程序,只需要名称和参数。 (正如@mob在评论中指出的那样,有些情况下仍然需要这样做;如果感兴趣,请参阅perlsub以了解更多信息。)
答案 2 :(得分:6)
我相信你想要
my %hash;
$hash{'1'}= {'Make' => 'Toyota','Color' => 'Red',};
$hash{'2'}= {'Make' => 'Ford','Color' => 'Blue',};
$hash{'3'}= {'Make' => 'Honda','Color' => 'Yellow',};
printInfo(%hash);
sub printInfo{
my %hash = @_;
foreach my $key (keys %hash){
my $a = $hash{$key}{'Make'};
my $b = $hash{$key}{'Color'};
print "$a $b\n";
}
}
在printInfo(%hash)
行中,%hash
扩展为包含交替键值对的列表。
在printInfo
中,@_
是此列表,并分配给%hash
,它会再次创建带有列表中交替元素的相应值的键。
答案 3 :(得分:5)
传递哈希和数组的最佳方法是reference。引用只是将复杂数据结构作为单个数据点进行讨论的一种方式 - 可以存储在标量变量中(例如$foo
)。
阅读references,了解如何创建引用和取消引用引用,以便恢复原始数据。
非常基础:在数据结构之前加上反斜杠,以便引用到该结构。
my $hash_ref = \%hash;
my $array_ref = \@array;
my $scalar_ref = \$scalar; #Legal, but doesn't do much for you...
引用是原始结构的内存位置(加上结构的线索):
print "$hash_ref\n";
会打印出类似的内容:
HASH(0x7f9b0a843708)
要将引用恢复为可用格式,只需将引用放在前面的正确sigil中:
my %new_hash = %{ $hash_ref };
您应该学习使用引用,因为这是您在Perl中创建极其复杂的数据结构的方式,以及面向对象的Perl如何工作。
让我们假设您要将三个哈希值传递给子程序。这是三个哈希:
my %hash1 = ( this => 1, that => 2, the => 3, other => 4 );
my %hash2 = ( tom => 10, dick => 20, harry => 30 );
my %hash3 = ( no => 100, man => 200, is => 300, an => 400, island => 500 );
我将为他们创建参考
my $hash_ref1 = \%hash1;
my $hash_ref2 = \%hash2;
my $hash_ref3 = \%hash3;
现在只需传递参考资料:
mysub ( $hash_ref1, $hash_ref2, $hash_ref3 );
引用是标量数据,因此将它们传递给我的子例程没有问题:
sub mysub {
my $sub_hash_ref1 = shift;
my $sub_hash_ref2 = shift;
my $sub_hash_ref3 = shift;
现在,我只是取消引用它们,我的子程序可以使用它们。
my %sub_hash1 = %{ $sub_hash_ref1 };
my %sub_hash2 = %{ $sub_hash_ref2 };
my %sub_hash3 = %{ $sub_hash_ref3 };
您可以使用ref命令查看引用的内容:
my $ref_type = ref $sub_hash_ref; # $ref_type is now equal to "HASH"
如果您想确保传递正确类型的数据结构,这非常有用。
sub mysub {
my $hash_ref = shift;
if ( ref $hash_ref ne "HASH" ) {
croak qq(You need to pass in a hash reference);
}
另请注意,这些是内存引用,因此修改引用将修改原始哈希:
my %hash = (this => 1, is => 2, a => 3 test => 4);
print "$hash{test}\n"; # Printing "4" as expected
sub mysub ( \%hash ); # Passing the reference
print "$hash{test}\n"; # This is printing "foo". See subroutine:
sub mysub {
my $hash_ref = shift;
$hash_ref->{test} = "foo"; This is modifying the original hash!
}
这可能很好 - 它允许您修改传递给子例程的数据,或者坏 - 它允许您无意中修改传递给原始子例程的数据。
答案 4 :(得分:3)
您可以将其作为
传递do_hash_thing( %hash )
keys
和其他哈希运算符一样工作。列表的工作原理如下:
sub do_hash_thing {
my %hash = @_;
...
}
do_hash_thing( %hash );
这也允许你“流”哈希参数:
do_hash_thing( %hash_1, %hash_2, parameter => 'green', other => 'pair' );
参考作品如下:
sub do_hash_thing {
my $hash_ref = shift;
...
}
do_hash_thing( \%hash, @other_args );
这里是原型(\%@)
。原型使perl在第一个参数中查找散列并通过引用传递它。
sub do_hash_thing (\%@) {
my $hash_ref = shift;
...
}
do_hash_thing( %hash => qw(other args) );
# OR
do_hash_thing %hash => qw(other args);
警告:原型不适用于方法。