在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
为推广perl尽一点力,特将perl引用的一篇文章翻译了一下,没有仔细查错,有问题请和我联系。本文可以从下面地址获得英文版本:
perlreftut - Mark 的一个简单的'引用'教程
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
幸运地是,你只需要了解手册上10%的知识得到90%的好处。本文就是告诉你其中的10%。
-------------------------------------------------------------------------------- 谁需要复杂的数据结构? 你为什么需要一个列表的哈希结构呢?让我们来看一个简单的例子:你有一个包含城市和国家名称的文件,如下: Chicago, USA Finland: Helsinki. 一个很自然的解决方法是将国家的名称设置为一个哈希结构的键,和国家名称对应的健值是这些国家内的城市的一个数组。 每一次,你读取一行输入,将其分成国家和城市两个数据。查看'国家名称'的键所对应的城市列表,然后把新的城市加入那个列表中。当你完成了整个输入,然后将整个哈希中每个健对应的健值-城市名的列表作一个排序,然后打印出来。 如果哈希值不能是列表,你就无法完成工作了。在Perl 4中,哈希的值不能是列表。它们只能是字符串。所以你必须把所有的城市名合并成一个字符串。当需要输出时,你再把这个字符串分拆成一个列表,然后对列表排序,最后将列表中的数据转成字符串输出。这样做非常烦琐并容易出错。而且让人沮丧的是,Perl已经拥有的优秀的列表功能无法使用了。
-------------------------------------------------------------------------------- 解决方法 一个'引用'就是一个指向一个完整列表或完整哈希(或指向其他的东西,比如函数)的标量值。名字就是你比较熟悉的一种'引用'。 考虑一下美国的总统:一包杂乱的血肉。但是当我们谈到它,或者需要在计算机程序中描述它,你需要的只是一个简单的标量'George Bush'。 Perl中的'引用'就像列表和哈希的名字。它们是Perl中私有的,内部的名字,所以你可以确信它们是明确的,不像'George Bush', 一个'引用'只指向一个东西。你总是可以知道它指向什么。如果你有一个指向数组的'引用',你可以从它恢复出整个数组。如果你有一个指向哈希的'引用',你可以根据它恢复出整个哈希。但是这个'引用'仍旧是一个简单、紧凑的标量。 你不能使用一个健值是数组的哈希;哈希的健值必须是标量。我们被这个束缚住了。但是一个简单的'引用'能指向一个完整的数组,'引用'是标量,所以你可以使用指向数组的'引用'组成的哈希,它就像一个数组的哈希一样,和数据的哈希一样有用。 稍后我们会再回到这个‘城市-国家’的问题来。我们先来看一些操作'引用'的语法。
--------------------------------------------------------------------------------
创建规则 1 $aref = \@array; # $aref 保存着指向@array的'引用' $xy = $aref; # $xy 现在保存了指向 @array 的'引用' 创建规则 2 [ ITEMS ] 创建了一个新的、匿名的数组,并返回一个指向这个数组的'引用'。 { ITEMS } 创建了一个新的、匿名的哈希,并返回那个哈希的一个'引用'。 $aref = [ 1, "foo", undef, 13 ]; # 这里: 如果你只是编写符号 [], 你将得到一个新的、空匿名数组。如果你使用符号 {},就能得到一个新的、空匿名哈希。
下面是一个用法的一些例子: 数组: @a @{$aref} 一个数组 使用哈希的'引用'和数组的'引用'完全一样。 %h %{$href} 一个哈希 for my $element (@array) { for my $element (@{$aref}) { for my $key (keys %hash) { for my $key (keys %{$href}) { 使用规则 2 ${$aref}[3] 太难阅读,所以我们这样写 $aref->;[3]。 ${$href}{red} 写的太笨重, 所以我们这样写 $href->;{red}。 如果 $aref 保存的是一个数组的'引用',那么 $aref->;[3] 就是这个数组的第四个成员。不要和 $aref[3] 相混淆,这个代表的是一个完全不同的数组的第四个成员,这个迷惑的数组是@aref。 变量 $aref 和 @aref 是完全不相关的,就像 $item 和 @item 一样。 同样的, $href->;{'red'} 是哈希'引用' 的变量$href的一部分,甚至这是一个没有名字的哈希。而$href{'red'} 是另一个容易混淆的命名哈希 %href 的一部分。很容易忘记写上符号' ->;',如果出现这种情况,当你的程序从一个你不想取数据的数组和哈希中取出了成员,你会得到奇怪的计算结果。
首先,记住 [1, 2, 3] 创建了一个匿名数组,包含了 (1, 2, 3),然后返回一个数组的'引用'。 现在想一下: @a = ( [1, 2, 3], $a[1] 是其中的一个'引用'。它指向一个数组,这个数组包含了(4, 5, 6),因为这是一个数组的'引用',使用规则 2 告诉我们可以这样写 $a[1]->;[2],用来取得这个数组的第三个成员。 $a[1]->;[2] 值是6。 同样的,$a[0]->;[1] 值是 2。这里我们就像在使用一个二维数组;你可以是用 $a[ROW]->;[COLUMN] 来取得或设置数组中任何一行任何一列中的成员。 这些符号看起来还是有些麻烦,所以还有更加简单的用法:
我们可以用这个写法$a[1][2]来代替$a[1]->;[2];它们是相同的。相对于$a[0]->;[1] = 23,我们这样写$a[0][1] = 23;它们也是相同的。 现在它们看起来真的象二维数组了! 你可以发现为什么箭头这么重要。没有它们,我们必须这样写${$a[1]}[2],而不是$a[1][2]。对于三维数组,它们使我们可以简单地写成$x[2][3][5]而不是写成难读的${${$x[2]}[3]}[5]方式。
-------------------------------------------------------------------------------- 解决办法 1 my %table; %table 8 foreach $country (sort keys %table) { @cities = @array; 第2-7行负责创建数据结构,如下: 2 while (<>;) { 第6行将城市名放到对应的数组里面。$table{$country} 现在保存了一个'引用',它指向所对应的国家的城市的数组。第6行就象 push @array, $city; 这里有一个要点被我忽略了。第5行是不需要的。我们可以取掉它。 2 while (<>;) { 这是Perl,它会自己准确地完成工作。你想把一个Athens赋值给一个不存在地数组,那么Perl会帮助你创建一个新的、空的匿名数组,将它放到哈希%table里面去,然后把值 Athens 放到这个数组中。这个被称为'自动生成' --让事物自己自动产生出来。 Perl 发现在哈希里面没有这个键,就自动地创建了一个新的哈希记录。 Perl 发现你想要使用数组作为哈希的健值,它就自动创建一个匿名的空数组,并将指向这个数组的'引用'放到那个哈希中去。一般, Perl 创建的数组只有一个成员大小,用于保存这个新的城市名。
-------------------------------------------------------------------------------- 其他集锦 手册 the perlref manpage中的一些集锦: 你可以对任何东西创建'引用',包括标量,函数和其他的引用。 在 使用规则 1 中,当大括号里面是一个象$aref这样的标量变量时,你可以省略掉这个大括号。例如, @$aref 和 @{$aref}是一样的,$$aref[1] 和 ${$aref}[1]是一样的。 如果你是初学者,建议你还是养成加上大括号的习惯。 下面的操作不会copy '引用'指向的数组: 要copy这个数组,你需要这样 $aref2 = [@{$aref1}]; 同样的,要copy一个匿名哈希,你需要这样 $href2 = {%{$href1}}; 如果要判断一个变量保存的内容是不是'引用',使用函数ref 。如果它的参数是'引用',返回的值是'真'。实际上,它做得更好:如果是一个哈希的引用,它返回'HASH',如果是一个数组的引用,那么就返回'ARRAY'。 如果你想像字符串一样使用'引用'的话,你得到的字符串就像 这种显示方式的另一个作用是你可以用eq来比较两个'引用',看它们是不是指向相同的东西。(你通常可以使用 == 来比较,因为它更会)
你可能更喜欢查看 the perllol manpage,而不是手册 the perlref manpage;它详细地讨论了列表的列表和多纬数组。然后,你可以继续学习手册 the perldsc manpage;它是数据结构的Cookbook, 它提供了处理哈希的数组,数组的哈希,以及其他数据结构的方法。
-------------------------------------------------------------------------------- 摘要
-------------------------------------------------------------------------------- 感谢 这篇文章最初出现在 The Perl Journal ( http://www.tpj.com/ ) volume 3, #2. 同意再版. 原来的标题是 Understand References Today.
This documentation is free; you can redistribute it and/or modify it under the same terms as Perl itself. Irrespective of its distribution, all code examples in these files are hereby placed into the public domain. You are permitted and encouraged to use this code in your own programs for fun or for profit as you see fit. A simple comment in the code giving credit would be courteous but is not required. perlreftut - Mark's very short tutorial about references |
请发表评论