Perl学习笔记 引用和匿名(数组/散列/子例程)

来源:转载

引用

Perl的标量变量保存单个值;数组保存一个有序的标量变量;散列保存一个无序的标量集合作为值


个人觉得,正是因为有引用,将标量、数组和散列很好的结合在一起,才在处理复杂的数据结构中游刃有余,引用可以分别数组引用和散列引用,还有个是子例程引用


数组引用


数组引用可以将数组和标量联系在一起


$result = /@array;

从标量再变回数组则叫做解引用


@array_2 = @{$result};

如果想访问@array数组的第一个元素,下述三种方式是等价的,个人喜欢第三种(其实是书中对引用如何可以进行省略的缩写,但是个人觉得还是按照正常写法更加能让别人看懂,不然代码可能会让大部分人都会搞晕了)


$a = $array[0];
$a = ${$result}[0];
$a = $result -> [0];

散列引用


其实对散列引用,也可以粗略理解为将散列转化为标量,那么散列和标量以及数组的又联系到了一起,用法跟数组引用一样,也是用反斜杠进行引用,然后用大括号进行解引用,最后在访问散列中的某个键对应的值


$result = /%hash;
%hash_2 = %{$result};
$a = ${$result}{"one"};
$a = ${$result} -> {"one"};

其实将散列引用解引用后,就是一个正常的散列了,可以随意的使用(同样的,这里的大括号也是可以省略的,但是我一般都不省略,以防万一以后理解错了。。)


@key = keys %{$result};

将散列引用存入数组中,这样有效地将散列和数组结合在一起使用,然后在后续有需要的时候解引用后即可返回为散列


@array = (/%hash, /%tmp);
%hash_2 = %{$array[0]};

子例程引用


理解了上述2个引用,那么子例程也是相同的用法


sub sum {
my @array = @_;
my $sum = 0;
map{
$sum += $_;
}@array;
return($sum);
}
my $function = /∑

引用后肯定也要解引用,子例程的解引用则是用小括号,比如用上述子例程对@array数组求和,同样也是用箭头使代码美观


$array_sum = &$function(@array);
$array_sum = $function -> (@array);
匿名

引用是Perl处理复杂数据结构的有力工具的话,那么个人认为匿名则是将其功能进一步升华了。


先简单的介绍下怎么算是匿名数组,如果正常的引用过程是如下:


@tmp = ("a", "bb", "ccc");
$result = /@tmp;

那么按照匿名数组的写法则是如下,可以有效的减少动用脑细胞去思考该如何命名上面的那个@tmp数组


$result = ["a", "bb", "ccc"];

会了匿名数组的写法,那么下述的数组中含有数组就很好理解了


@array = (["a", "bb", "ccc"], "dddd");
@array = (["a", "bb", "ccc"], ["d", "ee", "fff"]);

那么应该就很好理解什么是二维数组了,所谓二维数组,就是上述的代码,数组有匿名数组;对数组里的第一个元素解引用,然后再读取解引用后的数组的第一个元素赋值于新的标量,可用箭头增加代码的可读性


$result = $array[0] -> [0];

了解了匿名数组,那么匿名散列也是相同的意思,不同于匿名数组是用中括号,匿名散列则是用大括号表示


@array = (
{
a => "aa",
b => "bb",
},
{
c => "cc",
d => "dd",
},

那么二维散列可以理解为散列里面有匿名散列


%hash = {
x =>{
a => "aa",
b => "bb",
},
c => "cc",
}
$result = $hash{x} -> {a}

匿名子例程也是跟匿名数组和匿名散列的理解一样,为了减少临时的命名,比如对上述的求和子例程,就可以写成下面这种简单的形式:


$function = sub {
my @array = @_;
my $sum = 0;
map{
$sum += $_;
}@array;
return($sum);
}
$array_sum = $function -> (@array);

如果将匿名子例程放入一个子例程中,比如将匿名子例程放入一个find子例程中:


find(
sub {
my $a = "aaa";
print $a."/n";
},
$path,
)

其实个人觉得匿名数组和匿名散列最大的作用在于Perl会自动创建空的匿名数组/散列的引用,比如下面的代码就非常实用


push @{$hash{$i}}, "aaa";


上面这个代码的理解是:在运行这个代码之前,$hash{$i}
并不存在,但是在运行代码时,我们设置了一个数组引用@{$hash{$i}}
,那么Perl就会自动创建一个匿名数组,只是在push
之前,这个匿名数组是空的。


然后可以引申出在标量前面加个@就能转化为数组


@{$tmp} = (1,2,3);

并也可以对二维数组进行直接赋值,尽管这个二维数组之前还并不存在,这样导致了我们认为创建了一个新的有2个元素的数组,并在这个数组的第二个元素上写入了一个匿名数组,然后将”a”赋值于这个匿名数组的第3个元素。


$tmp[1] -> [2] = "a";

出了数组可以像上述这样操作,散列也是可以的,以二维散列的形式对其赋值


$hash{$a} -> {$b} = "c";

然后我们就可以用foreach循环提取出所有的键以及对应的值


foreach my $key1 (keys %hash){
foreach my $key2 (keys %{$hash{$key1}}){
$result = $hash{$key1} -> {$key2}
}
}

至于子例程的引用和匿名子例程的使用,能够帮我们很好的理解面向对象的使用,有些Perl的模块的使用,就是在调用其子例程的引用



本文出自于http://www.bioinfo-scrounger.com
转载请注明出处


分享给朋友:
您可能感兴趣的文章:
随机阅读: