【问题标题】:How do I dereference this hash in perl?如何在 perl 中取消引用此哈希?
【发布时间】:2015-11-04 00:04:50
【问题描述】:
#!/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);

这会产生以下输出:

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;

我尝试按照How do I dereference a Perl hash reference that's been passed to a subroutine?中的示例进行操作

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

【问题讨论】:

  • 您在创建列表时将其展平。您需要改用引用:(a => [1, 2, 3], b => [3, 4, 5]).
  • 请注意,您的giveMeARef 非常浪费。应该是:sub giveMeARef { my $hash = $_[0]; pop(@{ $hash->{a} }); }
  • 你打算做什么?只需打印数组或访问其元素?
  • @ikegami 你说的浪费是什么意思?
  • 不必要地复制哈希是浪费时间和内存

标签: perl hash reference subroutine


【解决方案1】:

正如我在comment 中提到的,当您创建%hash 时,您正在展平列表。粗逗号 (=>) 是逗号的同义词,它导致左侧的裸词被解释为字符串,但在这种情况下并不重要,因为左侧已经有了一个字符串。实际上,您的哈希分配看起来像这样:

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

看起来您试图将数组分配给 ab,但在 Perl 中,哈希值始终是标量,因此您需要使用对匿名数组的引用:

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

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

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);

哪些输出:

{ a => [1, 2, 3], b => [3, 4, 5] }
{ a => [1, 2], b => [3, 4, 5] }

【讨论】:

  • 最好不要复制引用的哈希值。
【解决方案2】:

代码没问题,但你的测试哈希不是你想象的那样。

你不能构造这样的哈希。那里的名单被弄平了。您需要改用数组引用:

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

既然您无论如何都要引用该哈希,那么您不妨从那里开始:

my $hash_ref = { a => [1,2,3], b => [3,4,5] };

【讨论】:

    【解决方案3】:

    这里有两个问题:

    • Dumper 用于在不传递引用的情况下打印散列的方式,其中它解析为将所有元素打印为 $VAR1、$VAR2 等。

      Dumper(\%hash)

    • 哈希的初始化方式。由于值是一个列表,所以应该初始化为

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

    更正确的代码。

    #!/usr/bin/perl
    use Data::Dumper;
    
    sub giveMeARef {
        my %hash = %{$_[0]};
    
        print "arg: ", Dumper($_[0]); #Dumper is passed a Ref.
        print "deref: ", Dumper(\%hash); # Dumper should be called with a hash ref.
    }
    
    my %hash = ( "a" => [1,2,3], "b" => [3,4,5]);
    
    giveMeARef(\%hash);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-10-11
      • 2016-06-17
      • 1970-01-01
      • 2013-02-06
      • 2018-02-25
      • 1970-01-01
      • 2014-05-08
      • 2014-04-13
      相关资源
      最近更新 更多