问题描述
我想正确理解Perl中的哈希。我不得不间歇地使用Perl一段时间,大多数时候我需要这样做,它主要与文本处理有关。
每次,我都必须处理随着哈希,它会变得混乱。我发现哈希的语法非常模糊
散列和哈希引用的一个很好的解释,它们的区别,当它们被需要时等等,我们将非常感激。
简单的哈希函数接近数组。他们的初始化甚至看起来相似。首先是数组:
@last_name =(
Ward,Cleaver,
Fred ,Flintstone,
Archie,Bunker
);
现在让我们使用散列表示相同的信息(又名关联数组):
%last_name =(
Ward,Cleaver,
Fred,Flintstone,
Archie,Bunker
);
尽管它们具有相同的名称,但数组 @last_name
和散列%last_name
是完全独立的。
有了数组,如果我们想知道Archie的姓氏,我们必须执行线性搜索:
my $ lname; ($ my $ i = 0; $ i $ lname = $ last_name [$ i + 1]
if $ last_name [$ i] eq阿尔奇;
}
打印Archie $ lname\\\
;
使用散列,它在语法上更直接:
打印Archie $ last_name {Archie} \\\
;
假设我们只想用稍微丰富的结构表示信息:
- 切割者(姓氏)
- 病房(名)
- 6月(配偶的名字)
- 石碑
- Fred
- Wilma
- Bunker
- Archie
- Edith
在引用出现之前,平键值散列是我们可以做的最好的,但引用允许
my% personal_info =(
Cleaver,{
FIRST,Ward,
SPOUSE,June,
},
Flintstone, {
FIRST,Fred,
SPOUSE,Wilma,
},
Bunker,{
FIRST,Archie ,
SPOUSE,Edith,
},
);
在内部,
%personal_info
都是标量,但这些值是一种特殊的标量:使用{}
创建的哈希引用。这些参考使我们能够模拟多维哈希。例如,我们可以通过
$ personal_info {Flintstone} - > {SPOUSE}
请注意,Perl允许我们在下标之间省略箭头,所以上面的内容相当于
$ personal_info {Flintstone} {SPOUSE}
如果您想了解有关Fred的更多信息,那么您可以输入很多内容,因此您可以使用某种游标获取引用:
$ fred = $ personal_info {Flintstone};
printFred的妻子是$ fred-> {SPOUSE} \\\
;
因为上面代码片段中的
$ fred
是一个hashref,箭头是必要的。如果你放弃它,但明智地启用使用strict
来帮助你捕捉这些类型的错误,编译器会抱怨:全局符号%fred需要显式包名称...
Perl引用与C和C ++中的指针类似,但它们不能为空。 C和C ++中的指针需要解引用,因此需要在Perl中引用。
C和C ++函数参数具有按值传递的语义:它们只是副本,不要回到调用者。如果你想看到更改,你必须传递一个指针。您可以在Perl中使用引用来获得这种效果:
sub add_barney {
my($ personal_info)= @_;
$ personal_info-> {Rubble} = {
FIRST => Barney,
SPOUSE => 贝蒂,
};
}
add_barney \%personal_info;
没有反斜线,
add_barney
一个副本在子回来后立即抛出。
还要注意使用胖逗号(
=>
)以上。它会自动引用左侧的字符串,并使得哈希初始化的语法更少。I would like to properly understand hashes in Perl. I've had to use Perl intermittently for quite some time and mostly whenever I need to do it, it's mostly related to text processing.
And everytime, I have to deal with hashes, it gets messed up. I find the syntax very cryptic for hashes
A good explanation of hashes and hash references, their differences, when they are required etc. would be much appreciated.
解决方案A simple hash is close to an array. Their initializations even look similar. First the array:
@last_name = ( "Ward", "Cleaver", "Fred", "Flintstone", "Archie", "Bunker" );
Now let's represent the same information with a hash (aka associative array):
%last_name = ( "Ward", "Cleaver", "Fred", "Flintstone", "Archie", "Bunker" );
Although they have the same name, the array
@last_name
and the hash%last_name
are completely independent.With the array, if we want to know Archie's last name, we have to perform a linear search:
my $lname; for (my $i = 0; $i < @last_name; $i += 2) { $lname = $last_name[$i+1] if $last_name[$i] eq "Archie"; } print "Archie $lname\n";
With the hash, it's much more direct syntactically:
print "Archie $last_name{Archie}\n";
Say we want to represent information with only slightly richer structure:
- Cleaver (last name)
- Ward (first name)
- June (spouse's first name)
- Flintstone
- Fred
- Wilma
- Bunker
- Archie
- Edith
Before references came along, flat key-value hashes were about the best we could do, but references allow
my %personal_info = ( "Cleaver", { "FIRST", "Ward", "SPOUSE", "June", }, "Flintstone", { "FIRST", "Fred", "SPOUSE", "Wilma", }, "Bunker", { "FIRST", "Archie", "SPOUSE", "Edith", }, );
Internally, the keys and values of
%personal_info
are all scalars, but the values are a special kind of scalar: hash references, created with{}
. The references allow us to simulate "multi-dimensional" hashes. For example, we can get to Wilma via$personal_info{Flintstone}->{SPOUSE}
Note that Perl allows us to omit arrows between subscripts, so the above is equivalent to
$personal_info{Flintstone}{SPOUSE}
That's a lot of typing if you want to know more about Fred, so you might grab a reference as sort of a cursor:
$fred = $personal_info{Flintstone}; print "Fred's wife is $fred->{SPOUSE}\n";
Because
$fred
in the snippet above is a hashref, the arrow is necessary. If you leave it out but wisely enableduse strict
to help you catch these sorts of errors, the compiler will complain:Global symbol "%fred" requires explicit package name at ...
Perl references are similar to pointers in C and C++, but they can never be null. Pointers in C and C++ require dereferencing and so do references in Perl.
C and C++ function parameters have pass-by-value semantics: they're just copies, so modifications don't get back to the caller. If you want to see the changes, you have to pass a pointer. You can get this effect with references in Perl:
sub add_barney { my($personal_info) = @_; $personal_info->{Rubble} = { FIRST => "Barney", SPOUSE => "Betty", }; } add_barney \%personal_info;
Without the backslash,
add_barney
would have gotten a copy that's thrown away as soon as the sub returns.Note also the use of the "fat comma" (
=>
) above. It autoquotes the string on its left and makes hash initializations less syntactically noisy.这篇关于Perl中的散列和散列引用有什么区别?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!