如何在perl中取消引用此哈希?

Fle*_*ore 0 perl hash reference subroutine

#!/usr/bin/perl
use Data::Dumper;

sub giveMeARef {
    my %hash = %{$_[0]};

    print "arg: ", Dumper($_[0]);
    print "deref: ", Dumper(%hash);
}

my %hash = ( "a" => (1,2,3), "b" => (3,4,5));

giveMeARef(\%hash);
Run Code Online (Sandbox Code Playgroud)

这会产生以下输出:

arg: $VAR1 = {
          '2' => 3,
          '4' => 5,
          'a' => 1,
          'b' => 3
        };
deref: $VAR1 = 'b';
$VAR2 = 3;
$VAR3 = '2';
$VAR4 = 3;
$VAR5 = 'a';
$VAR6 = 1;
$VAR7 = '4';
$VAR8 = 5;
Run Code Online (Sandbox Code Playgroud)

我试着按照如何取消引用已传递给子例程的Perl哈希引用中的示例

但我相信因为我的哈希更复杂,所以对我来说不合适.我如何回到我传入的原始结构?

Mat*_*cob 6

正如我在评论中提到的,当你创建时,你正在展平列表%hash.胖逗号(=>)是逗号的同义词,它使左边的裸字被解释为字符串,但在这种情况下无关紧要,因为你已经在左边有一个字符串.实际上,您的哈希分配看起来像这样:

my %hash = ("a", 1, 2, 3, "b", 3, 4, 5);
Run Code Online (Sandbox Code Playgroud)

看起来你试图将数组分配给ab,但是在Perl中,哈希值总是标量,所以你需要使用对匿名数组的引用:

my %hash = (a => [1, 2, 3], b => [3, 4, 5]);
Run Code Online (Sandbox Code Playgroud)

还值得注意的是,您的子例程正在为您传入的哈希引用制作一个浅表副本,这可能会产生意想不到/无法预料的后果.考虑以下:

use Data::Dump;

sub giveMeARef {
    my %hash = %{$_[0]};
    pop(@{$hash{a}});
}

my %hash = (a => [1, 2, 3], b => [3, 4, 5]);

dd(\%hash);
giveMeARef(\%hash);
dd(\%hash);
Run Code Online (Sandbox Code Playgroud)

哪个输出:

{ a => [1, 2, 3], b => [3, 4, 5] }
{ a => [1, 2], b => [3, 4, 5] }
Run Code Online (Sandbox Code Playgroud)