【转载】Perl中的引用
为什么使用引用?
在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 referencemy $aref = \@array ; # array referencemy $href = \%hash ; # hash reference # 方法一print $$sref, "\n" ; # 用$sref代替srefprint @$aref, "\n" ; # 用$aref代替aref print %$href, "\n" ; # 用$href代替hrefprint $$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 referencemy $aref = \@array ; # array referencemy $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],几乎没人这么写!
多维数组的另一个写法如下:
这两者的区别有以下几点:
- 前者是真正的数组,所以定义变量是使用@,后者是指向匿名数组的引用,所以定义的时候使用$
- 前者的数组元素是匿名数组,而外层数组则是实体数组,后者无论元素还是外层数组都是匿名数组
- 前者可以用$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 (==)
【转载】Perl中的引用的更多相关文章
- [Perl系列—] 2. Perl 中的引用使用方法
Perl 中的引用,为什么要使用引用? 对于熟悉C语言的开发人员来说, 指针这个概念一定不陌生. Perl 的引用就是指针,能够指向变量.数组.哈希表甚至子程序. Perl5中的两种Perl引用类型为 ...
- perl 中的引用
perl 语言中的引用共分为两类: 声明引用时只需要在对象的前面加上反斜杠 第一列是数组的引用: 代码示例: , , ); my $array_ref = \@array; 第二种是哈希的引用 代码示 ...
- perl中 use strict会出现“requires explicit package name”错误
转载 perl中use strict的用法 如果你使用 use strict 的话,它会强迫你用 my 声明变量,否则将会报上述错误.
- perl中sprintf函数的用法
对于某些字符串,需要输入为特定的格式,通过sprintf可以很方便的完成,不需要专门进行其他处理. 转载 perl中sprintf函数的使用方法.
- <转载>无法解析的外部符号 _main,该符号在函数 ___tmainCRTStartup 中被引用
转载http://blog.sina.com.cn/s/blog_6e6c5f230100p92p.html 无法解析的外部符号 _main,该符号在函数 ___tmainCRTStartup 中被引 ...
- (转载)理解Java中的引用传递和值传递
关于Java传参时是引用传递还是值传递,一直是一个讨论比较多的话题,有论坛说Java中只有值传递,也有些地方说引用传递和值传递都存在,比较容易让人迷惑.关于值传递和引用传递其实需要分情况看待,今天 ...
- 【转载】Perl中字符串编码的处理
在 Perl看来, 字符串只有两种形式. 一种是octets, 即8位序列, 也就是我们通常说的字节数组. 另一种utf8编码的字符串, perl管它叫string. 也就是说: Perl只熟悉两种编 ...
- Perl中的正则表达式
转自:http://c20031776.blog.163.com/blog/static/684716252013624383887/ Perl 程序中,正则表达式有三种存在形式 分别是 (1 模式匹 ...
- Perl中的匹配(六)
在Perl中,匹配的定界符如果是双斜线//,可以直接使用双斜线完成匹配操作. 如果特定条件下需要改变定界符,如改为{},[]等.需要加入m,m{},m[]等. m%^http://% 默认的模式匹配对 ...
随机推荐
- Python基础学习参考(七):字典和集合
一.字典 字典跟列表一样是一组数据的集合.它的特点是什么呢? 特点一:字典具有键(key)和值(value),其中键必须是唯一的,不可重复的,即键必须可以哈希的.对于值没有要求. 特点二:字典是无序的 ...
- Integer 与 int
Integer是java为int提供的封装类.int的默认值为0,而Integer的默认值为null,即Integer可以区分出未赋值和值为0的区别,int则无法表达出未赋值的情况 例如,要想表达出没 ...
- python︱模块加载(pip安装)以及pycharm安装与报错解决方式
每每以为攀得众山小,可.每每又切实来到起点,大牛们,缓缓脚步来俺笔记葩分享一下吧,please~ --------------------------- 准备放下R开始学python,真是痛苦,因为找 ...
- HI3531uboot开机画面
startvo 0 36 13; startgx 0 0x88000000 1600 0 0 800 600; //startgx 0 0x88000000 2048 0 0 1024 768; se ...
- R语言︱文件读入、读出一些方法罗列(批量xlsx文件、数据库、文本txt、文件夹)
笔者寄语:小规模的读取数据的方法较为简单并且多样,但是,批量读取目前看到有以下几种方法:xlsx包.RODBC包.批量转化成csv后读入. R语言中还有一些其他较为普遍的读入,比如代码包,R文件,工作 ...
- 错误代码: 1111 Invalid use of group function
1.错误描述 1 queries executed, 0 success, 1 errors, 0 warnings 查询:update t_user_info t inner join t_pro_ ...
- Java并发 线程池
线程池技术就是事先创建一批线程,这批线程被放入到一个池子里,在没有请求到达服务端时候,这些线程都是处于待命状态,当请求到达时候,程序会从线程池里取出一个线程,这个线程处理到达的请求,请求处理完毕,该线 ...
- Unity开发之实现更换鼠标图片
在玩游戏的时候,感觉游戏里的鼠标图片特酷炫,23333,今天我就总结了两种方法! 我是做Unity开发的,所以方法仅针对于Unity平台........ 方法如下: 1.Unity客户端直接更改,步骤 ...
- angular路由参数说明
AngularJS 路由 本章节我们将为大家介绍 AngularJS 路由. AngularJS 路由允许我们通过不同的 URL 访问不同的内容. 通过 AngularJS 可以实现多视图的单页Web ...
- iOS - EaseMob 环信的使用
1.环信 环信使用的是 XMPP 协议,它是在 XMPP 的基础上进行的二次开发,对服务器 Openfire 和客户端进行功能模型的添加和客户端 SDK 的封装.环信的本质还是使用 XMPP,基于 S ...