设为首页 收藏本站
查看: 1157|回复: 0

[经验分享] perl中的引用

[复制链接]

尚未签到

发表于 2015-12-27 09:46:33 | 显示全部楼层 |阅读模式
为什么使用引用?
  在perl4中,hash表中的value字段只能是scalar,而不能是list,这对于有些情况是很不方便的,比如有下面的数据:
  Chicago, USA Frankfurt, Germany Berlin, Germany Washington, USA Helsinki, Finland New York, USA
  我们想要按国家将城市分类,每个国家后面对应城市列表,如果用perl4来做,必须将城市列表组合成字符串才行,如果用perl5就可以用引用来做,有了引用,就可以构造复杂的hash结构,就可以用列表作为hash的值了。

如何定义引用

方法一 使用斜线\
  定义变量的时候,在变量名前面加个\,就得到了这个变量的一个引用,比如





# 数组的引用my@array= (1,2,3) ; my$aref=\@array ;
#哈希的引用my%hash= ("name"=>"zdd","age"=>30,"gender"=>"male") ; my$href=\%hash ;
#标量的引用my$scalar=1 ; my$sref=\$scalar ;


方法二 匿名引用
  方法一不是很常用,最常用的还是匿名引用,方法如下
  匿名数组引用-用[]定义



$aref= [ 1,"foo",undef,13 ];
  匿名数组的元素仍然可以是匿名数组,所以我们可以用这种方法构造数组的数组,可以构造任意维度的数组。



my $aref = [         [1, 2, 3],         [4, 5, 6],         [7, 8, 9], ]
  匿名哈希引用-用{}定义



$href= { APR =>4, AUG =>8 };
使用引用
  定义了引用之后,可以使用不同的方法来访问引用,这里主要有三种方法。记忆这三种方法有个诀窍,将他们与普通的变量访问作比较即可。

方法一
  与普通变量的访问方法相比,假设原来的变量名是name,则此方法在所有name出现的地方用$name代替,如下





my $scalar = 1 ;
my @array = (1, 2, 3) ;
my %hash = ('zdd' => 30, 'autumn' => 27) ;
my $sref = \$scalar ;   # scalar reference
my $aref = \@array ;    # array referencem
y $href = \%hash ;     # hash reference
# 方法一
print $$sref, "\n" ;  # 用$sref代替sref
print @$aref, "\n" ;   # 用$aref代替aref  
print %$href, "\n" ;   # 用$href代替href
print $$aref[2], "\n" ;
print $$href{'zdd'}, "\n" ;


方法二
  与普通变量的访问方法相比,假设变量原来的名字是name,则现在用{$name}来代替name。



@a        @{$aref}         
An array    reverse@a  reverse @{$aref}    Reverse the array   
$a[3]      ${$aref}[3]       An element of the array   
$a[3] =17;   ${$aref}[3] =17    Assigning an element
  同理,哈希引用的使用方法如下。



%h          %{$href}           A hash   
keys%h      keys%{$href}        Get the keys from the hash   
$h{'red'}      ${$href}{'red'}       An element of the hash   
$h{'red'} =17   ${$href}{'red'} =17    Assigning an element
  注意:当{}内部是$var的形式时,{}是可以省略的,也就是说@{$aref}等价于@$aref,不过初学最好养成使用{}的习惯。

方法三
  前两种方法比较繁琐,这种很简洁,就是使用箭头符号->
  $aref->[]  数组解引用
  $href->{}  哈希解引用
  $href->()  子过程解引用



$aref->[0] =3 ;  $href->{name} ="autumn" ;  $sref=2 ;
  也可以将引用赋值给其他变量



my$aref1=$aref ; my$href1=$href ; my$scalar1=$scalar ;
解引用总结





my $scalar = 1 ;
my @array = (1, 2, 3) ;
my %hash = ('zdd' => 30, 'autumn' => 27) ;
my $sref = \$scalar ;   # scalar reference
my $aref = \@array ;    # array referencem
y $href = \%hash ;     # hash reference #
方法一
print $$sref, "\n" ;
print @$aref, "\n" ;
print %$href, "\n" ;
print $$aref[2], "\n" ;
print $$href{'zdd'}, "\n" ;
# 方法二
print ${$sref}, "\n" ;
print @{$aref}, "\n" ;
print %{$href}, "\n" ;
print ${$aref}[2], "\n" ;
print ${$href}{'zdd'}, "\n" ;
# 方法三,不适用于标量
print $aref->[0], "\n" ;
print $href->{'zdd'}, "\n" ;


数组的数组



@a = (     [1, 2, 3],     [4, 5, 6],     [7, 8, 9] )
  我们知道[1, 2, 3]定义了一个(1, 2, 3)的匿名引用,所以数组a实际上包含三个元素,每个元素是一个引用,该引用指向一个数组,所以我们可以用下面的方法来访问数组元素(注意,下标从0开始)
  $a[1][2]表示第二行第三列元素6,也可以写成$a[1]->[2],不过很少有人这么写。还可以写成${$a[1]}[2],几乎没人这么写!
  多维数组的另一个写法如下:



my $aref = [1, [2, 3], [4, 5, 6]] ;
print $aref->[0] , "\n" ; #1
print $aref->[1][1], "\n" ; #3
print $aref->[2][0], "\n" ; #4
  这两者的区别有以下几点:


  • 前者是真正的数组,所以定义变量是使用@,后者是指向匿名数组的引用,所以定义的时候使用$
  • 前者的数组元素是匿名数组,而外层数组则是实体数组,后者无论元素还是外层数组都是匿名数组
  • 前者可以用$a[x][y]的形式访问,而后者只能用解引用的方式访问,即$a->[x][y]的形式。
  数组的哈希
  哈希的数组

哈希的哈希
  也就是哈希表中的每个元素也是一个哈希表,比如一个学生集合组成的哈希,其key是学生名字(唯一),其值是每个学生的属性,比如年龄,身高及学号等。





my $student_properties_of = {   
'zdd' => {      'age' => 30,         'hight' => 170,         'id' => '001',     },
'autumn' => {         'age' => 27,         'hight' => 165,         'id' => '002',     }
                 } ;


引用的赋值
  $aref2 = $aref1; 将使得$aref2和$aref1指向同一个数组,如果想将$aref1指向的数组拷贝一份给$aref2的话,使用下面的方法,[]里面对数组进行解引用,而[]以解引用后的数组为内容生成了一个新的匿名数组,又赋值给$aref2。



$aref2 = [@{$aref1}];
  注意:不能使用下面的形式,外层的[]是不可缺少的。由于=左边是标量,所以右边的数组会被解释为标量环境,得到的是数组元素个数,而不是元素本身。但是如果加上[]就可以了,这样perl知道这是一个匿名数组的赋值。

$aref2 = @{$aref1};
判断一个变量是否是引用
  使用ref函数即可,如果变量是引用则返回真,否则返回假。实际上它更智能,它会返回引用对应的类型,比如HASH或者ARRAY。



my $aref1 = [1, 2, 0] ;
print ref $aref1, "\n" ; #输出 ARRAY
if (ref $aref1)
{     print "true\n" ; #输出 true }
判断两个引用是否指向同一个目标
  可以用eq,这将以字符串的形式判断,也可以使用==




my $aref1 = [1, 2, 0] ;

my $aref2 = $aref1 ;

print $aref1, "\n" ;

print $aref2, "\n" ;
if ($aref1 eq $aref2)

  {     print "reference equal\n" ; }

if($aref1 == $aref2)

  {     print "reference equal\n" ; }

  产生如下输出
  ARRAY(0x248bec) ARRAY(0x248bec) reference equal (eq) reference equal (==)

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-156833-1-1.html 上篇帖子: Perl 未完工的爬虫 下篇帖子: Perl语言入门-第四章-子程序-习题
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表