我如何在 perl 中取消引用这个散列?
How do I dereference this hash in perl?
#!/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?
中的示例进行操作
但我相信因为我的哈希更复杂,所以它不适合我。如何返回到我传入的原始结构?
代码没问题,但你的测试散列不是你想的那样。
你不能构造那样的散列。那里的清单变得扁平化了。您需要改用数组引用:
my %hash = ( "a" => [1,2,3], "b" => [3,4,5]);
既然你无论如何都要引用那个散列,你不妨从这里开始:
my $hash_ref = { a => [1,2,3], b => [3,4,5] };
正如我在 中提到的,您在创建 %hash
时会展平列表。粗逗号 (=>
) 是导致左侧的裸词被解释为字符串的逗号的同义词,但在这种情况下无关紧要,因为左侧已经有一个字符串。实际上,您的哈希分配看起来像这样:
my %hash = ("a", 1, 2, 3, "b", 3, 4, 5);
看起来您试图将数组分配给 a
和 b
,但在 Perl 中,散列值始终是标量,因此您需要改用对匿名数组的引用:
my %hash = (a => [1, 2, 3], b => [3, 4, 5]);
还值得注意的是,您的子例程正在对您传入的散列引用进行浅表复制,这可能会产生 unintended/unforeseen 后果。考虑以下因素:
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] }
这里有两个问题:
Dumper 用于在不传递引用的情况下打印散列的方式,其中它解析为将所有元素打印为 $VAR1、$VAR2 等
转储程序(\%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);
#!/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?
中的示例进行操作但我相信因为我的哈希更复杂,所以它不适合我。如何返回到我传入的原始结构?
代码没问题,但你的测试散列不是你想的那样。
你不能构造那样的散列。那里的清单变得扁平化了。您需要改用数组引用:
my %hash = ( "a" => [1,2,3], "b" => [3,4,5]);
既然你无论如何都要引用那个散列,你不妨从这里开始:
my $hash_ref = { a => [1,2,3], b => [3,4,5] };
正如我在 %hash
时会展平列表。粗逗号 (=>
) 是导致左侧的裸词被解释为字符串的逗号的同义词,但在这种情况下无关紧要,因为左侧已经有一个字符串。实际上,您的哈希分配看起来像这样:
my %hash = ("a", 1, 2, 3, "b", 3, 4, 5);
看起来您试图将数组分配给 a
和 b
,但在 Perl 中,散列值始终是标量,因此您需要改用对匿名数组的引用:
my %hash = (a => [1, 2, 3], b => [3, 4, 5]);
还值得注意的是,您的子例程正在对您传入的散列引用进行浅表复制,这可能会产生 unintended/unforeseen 后果。考虑以下因素:
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] }
这里有两个问题:
Dumper 用于在不传递引用的情况下打印散列的方式,其中它解析为将所有元素打印为 $VAR1、$VAR2 等
转储程序(\%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);