neb*_*lus 20 perl hash subroutine
需要帮助搞清楚如何做到这一点.我的代码:
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";
}
}
Run Code Online (Sandbox Code Playgroud)
gha*_*ndi 35
在代码发展时可能导致问题的简单方法就是将默认数组@_(包含所有键值对作为偶数列表)分配给%hash,然后根据其重建.所以你的代码看起来像这样:
sub printInfo {
my %hash = @_;
...
}
Run Code Online (Sandbox Code Playgroud)
更好的方法是将哈希作为对子例程的引用传递.这样,您仍然可以将更多参数传递给子例程.
printInfo(\%hash);
sub PrintInfo {
my %hash = %{$_[0]};
...
}
Run Code Online (Sandbox Code Playgroud)
在perlreftut中可以找到在Perl中使用引用的介绍
你非常非常接近.没有%_通过哈希,它必须传递@_.幸运的是,哈希是使用列表上下文分配的,所以
sub printInfo {
my %hash = @_;
...
}
Run Code Online (Sandbox Code Playgroud)
会让它发挥作用!
还要注意,&在大多数情况下,使用子程序调用前面的参数至少是Perl 5.000.这些天你可以像其他语言一样调用Perl子程序,只需要名称和参数.(正如@mob在评论中指出的那样,在某些情况下,这仍然是必要的; 如果感兴趣,请参阅perlsub以了解更多信息.)
我相信你想要的
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";
}
}
Run Code Online (Sandbox Code Playgroud)
在该行中printInfo(%hash),它%hash被扩展为具有交替键值对的列表.
在printInfo,@_该列表中,并且分配给%hash它再次创建具有来自列表中的交替元素的对应值的键.
传递哈希和数组的最佳方法是引用.引用只是将复杂数据结构作为单个数据点进行讨论的一种方式 - 可以存储在标量变量(如$foo)中.
阅读参考资料,以便了解如何创建参考文献并取消参考参考资料以获取原始数据.
非常基础:在数据结构之前加上反斜杠以获取对该结构的引用.
my $hash_ref = \%hash;
my $array_ref = \@array;
my $scalar_ref = \$scalar; #Legal, but doesn't do much for you...
Run Code Online (Sandbox Code Playgroud)
引用是原始结构的内存位置(加上结构的线索):
print "$hash_ref\n";
Run Code Online (Sandbox Code Playgroud)
将打印像:
HASH(0x7f9b0a843708)
Run Code Online (Sandbox Code Playgroud)
要将引用恢复为可用格式,只需将引用放在前面的正确 符号中:
my %new_hash = %{ $hash_ref };
Run Code Online (Sandbox Code Playgroud)
您应该学习如何使用引用,因为这是您在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 );
Run Code Online (Sandbox Code Playgroud)
我将为他们创建参考
my $hash_ref1 = \%hash1;
my $hash_ref2 = \%hash2;
my $hash_ref3 = \%hash3;
Run Code Online (Sandbox Code Playgroud)
现在只需传递参考:
mysub ( $hash_ref1, $hash_ref2, $hash_ref3 );
Run Code Online (Sandbox Code Playgroud)
引用是标量数据,因此将它们传递给我的子例程没有问题:
sub mysub {
my $sub_hash_ref1 = shift;
my $sub_hash_ref2 = shift;
my $sub_hash_ref3 = shift;
Run Code Online (Sandbox Code Playgroud)
现在,我只是取消引用它们,我的子程序可以使用它们.
my %sub_hash1 = %{ $sub_hash_ref1 };
my %sub_hash2 = %{ $sub_hash_ref2 };
my %sub_hash3 = %{ $sub_hash_ref3 };
Run Code Online (Sandbox Code Playgroud)
您可以使用ref命令查看引用的引用:
my $ref_type = ref $sub_hash_ref; # $ref_type is now equal to "HASH"
Run Code Online (Sandbox Code Playgroud)
如果您想确保传递正确类型的数据结构,这非常有用.
sub mysub {
my $hash_ref = shift;
if ( ref $hash_ref ne "HASH" ) {
croak qq(You need to pass in a hash reference);
}
Run Code Online (Sandbox Code Playgroud)
另请注意,这些是内存引用,因此修改引用将修改原始哈希:
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!
}
Run Code Online (Sandbox Code Playgroud)
这可能很好 - 它允许您修改传递给子例程的数据,或者坏 - 它允许您无意中修改传递给原始子例程的数据.