簡體   English   中英

如何將哈希傳遞給子例程?

[英]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!
}

這可能很好 - 它允許您修改傳遞給子例程的數據,或者壞 - 它允許您無意中修改傳遞給原始子例程的數據。

你可以傳遞它們

  1. 參數列表do_hash_thing( %hash )
  2. 參數列表中的哈希引用`do_hash_thing(@ args_before,\\%hash,@ args_after)
  3. 作為原型的參考,像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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM