我正在尝试学习参考函数,但我无法找到一种方法同时将哈希值放在引用中。我想编写一个子程序,它将两个简单的哈希引用作为参数,并检查这两个哈希值是否相等。我的代码是:
selectedFoo
但是,我收到了这些错误:
(change)
任何解决方案?任何帮助将不胜感激!
答案 0 :(得分:4)
答案 1 :(得分:3)
你已经接受了一个很好的答案。但是对于将来发现这个问题的人来说,我认为值得解释一些你所犯的错误。
首先定义一些匿名哈希值。没关系。
my $hash1_r = {
ITALY => "ROME",
FRANCE => "PARIS"
};
my $hash2_r = {
ITALY => "MILAN",
FRANCE => "PARIS"
};
my $hash3_r = {
ITALY => "ROME"
};
my $hash4_r = {
SPAIN => "ROME",
FRANCE => "PARIS"
};
我现在要跳到您调用子程序的地方(我很快就会回到子程序)。
compareHashes (%$hash1_r, %$hash1_r);
compareHashes (%$hash1_r, %$hash2_r);
compareHashes (%$hash1_r, %$hash3_r);
compareHashes (%$hash1_r, %$hash4_r);
引用最重要的用途之一是使您能够将多个数组和哈希值传递到子例程中,而不会将它们展平为单个数组。由于您已经有哈希引用,因此将这些引用传递给子例程是有意义的。但你不能这样做。您取消引用哈希值,这意味着您将实际哈希值发送到子例程中。这意味着,例如,您的第一个电话会在列表('ITALY', 'ROME', 'FRANCE', 'PARIS', 'ITALY', 'MILAN', 'FRANCE', 'PARIS')
中传递。并且子程序中的代码无法将该列表分成两个哈希值。
现在,让我们看看子程序本身。首先定义子例程的原型。在大多数情况下,原型是不必要的。在许多情况下,它们以难以理解的方式更改代码行为。没有Perl专家会建议在此代码中使用原型。并且,正如您的错误消息所示,您的原型错误。
sub compareHashes(%$hash1, %$hash2){
我不确定你要用这个原型做什么。也许它根本不是原型 - 也许它只是function signature(但如果是的话,你需要打开这个功能)。
在下一行中,您声明了两个变量。您永远不会给予值的变量。
my $hash1; my $hash2;
然后有两个非常混乱的for
循环。
for (my $i =0; $i < keys %$hash1; $i++){
say "The first hash:";
say "keys %$hash1\t, values %$hash1";
}
$hash1
没有任何价值。所以%$hash1
为零(散列没有键)并且循环没有被执行。但是我们并没有错过很多,因为循环体每次只打印相同的未初始化值。
您可以通过将for
样式循环简化为foreach
循环。
foreach my $i (0 .. keys %$hash1 - 1) { ... }
或者(假设您根本不使用$i
:
foreach (1 .. keys %$hash1) { ... }
对for
的另一个同样无效的$hash2
循环,你试着比较你的两个哈希值。
for (keys %$hash1) {
if (keys %$hash1 ne keys %$hash2){
say "Two above hashes are not equal";
}elsif (my $key1 (keys %$hash1) ne my $key2 (keys %$hash2)){
say "Two above hashes are not equal";
}elsif (%$hash1->{$_} ne %$hash2->{$_}){
say "Two above hashes are not equal";
}else {
say "Two above hashes are equal";
}
}
我根本不知道为什么这一切都在for
循环中。但是你的比较并没有真正比较散列中的值。所有你要比较的是哈希中的键数(这里总是相等 - 因为你的哈希总是空的)。
总而言之,对于Perl中的哈希,子例程和引用如何工作,这是非常困惑的工作。我会敦促你停止你正在做的事情并花时间通过一本好的参考书,比如学习Perl ,接着是 Intermediate Perl ,然后再继续你当前的路线,只是让自己更加困惑。