[英]How do I pass a hash to 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";
}
}
在代碼發展時可能導致問題的簡單方法就是將默認數組@_(包含所有鍵值對作為偶數列表)分配給%hash,然后根據其重建。 所以你的代碼看起來像這樣:
sub printInfo {
my %hash = @_;
...
}
更好的方法是將哈希作為對子例程的引用傳遞。 這樣,您仍然可以將更多參數傳遞給子例程。
printInfo(\%hash);
sub PrintInfo {
my %hash = %{$_[0]};
...
}
在perlreftut中可以找到在Perl中使用引用的介紹
你非常非常接近。 傳遞哈希沒有%_
,它必須在@_
傳遞。 幸運的是,哈希是使用列表上下文分配的,所以
sub printInfo {
my %hash = @_;
...
}
會讓它發揮作用!
另請注意,在大多數情況下,使用子程序調用前面的&
,因為至少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";
}
}
在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...
引用是原始結構的內存位置(加上結構的線索):
print "$hash_ref\n";
將打印像:
HASH(0x7f9b0a843708)
要將引用恢復為可用格式,只需將引用放在前面的正確符號中:
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!
}
這可能很好 - 它允許您修改傳遞給子例程的數據,或者壞 - 它允許您無意中修改傳遞給原始子例程的數據。
你可以傳遞它們
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);
警告:原型不適用於方法。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.