我正在尝试编写一个子程序,它接受数组的哈希作为参数。但是,当我尝试检索其中一个数组时,我似乎得到了数组的大小而不是数组本身。
my(%hash) = ( );
$hash{"aaa"} = ["blue", 1];
_subfoo("test", %hash);
sub _subfoo {
my($test ,%aa) = @_;
foreach my $name (keys %aa) {
my @array = @{$aa{$name}};
print $name. " is ". @array ."\n";
}
}
这会像我预期的那样返回2而不是(蓝色,1)。在子例程中是否还有其他方法可以处理哈希中的数组?
道歉,如果这对于堆栈溢出,第一次海报和编程新手来说太简单了。
答案 0 :(得分:10)
您将@array
数组置于标量上下文中:
print $name. " is ". @array ."\n";
标量上下文中的数组为您提供数组中元素的数量,@array
恰好有2个元素。请尝试其中之一:
print $name . " is " . join(', ', @array) . "\n";
print $name, " is ", @array, "\n";
print "$name is @array\n";
您将看到@array
的元素。使用join
可以随意粘贴元素;第二个评估列表上下文中的@array
并将值混合在一起而不将它们分开;第三个插入@array
通过将其元素与$"
(默认为单个空格)连接起来。
答案 1 :(得分:4)
由于mu太短了,你在标量上下文中使用了数组,因此它返回了它的长度而不是它的元素。我还有一些关于你的代码的其他指示。
当其中一些参数是数组或散列时,通过引用传递参数有时是个好主意。这样做的原因是数组和散列在传递给子程序之前会扩展到列表中,这使得这样的事情变得不可能:
foo(@bar, @baz);
sub foo { # This will not work
my (@array1, @array2) = @_; # All the arguments will end up in @array1
...
}
然而,这将有效:
foo(\@bar, \@baz);
sub foo {
my ($aref1, $aref2) = @_;
...
}
您可能会发现,在您的情况下,each
对于您的目的来说是一个很好的功能,因为它会使阵列的解除引用更加整洁。
foo("test", \%hash); # note the backslash to pass by reference
sub foo {
my ($test, $aa) = @_; # note use of scalar $aa to store the reference
while (my ($key, $value) = each %$aa)) { # note dereferencing of $aa
print "$key is @$value\n"; # ...and $value
}
}