Perl匿名数组、hash和autovivification特性
可有构建匿名的对象,这样就没必要去为只用一两次的数组、hash去取名字,有时候取名是很烦的事。
构造匿名对象例如,在数组、hash中构建匿名数组: @name=('fairy',['longshuai','wugui','xiaofang']); %hash=('longshuai' => ['male',18,'jiangxi'],'wugui' => ['male',20,'zhejiang'],'xiaofang' => ['female',19,'fujian'],); say "$name[1]"; # 输出ARRAY(0x...) say "$hash{wugui}"; # 输出ARRAY(0x...) say "$name[1][2]"; say "$hash{wugui}[1]"; 如果不想在匿名数组中输入引号,可以使用qw()。 # 以下等价 @name=('fairy','xiaofang']); @name=('fairy',[qw(longshuai wugui xiaofang)]); 在数组、hash中构建匿名hash: @name=( # 匿名hash作为数组的元素 { # 第一个匿名hash 'name'=>'longshuai','age'=>18,'prov'=>'jiangxi',},{ # 第二个匿名hash 'name'=>'wugui','age'=>20,'prov'=>'zhejiang',{ # 第三个匿名hash 'name'=>'xiaofang','age'=>19,'prov'=>'fujian',); %hash=( # 匿名hash作为hash的value 'longshuai'=>{ # 第一个匿名hash 'gender'=>'male','age' =>18,'prov' =>'jiangxi','wugui'=>{ # 第二个匿名hash 'gender'=>'male','age' =>20,'prov' =>'zhejiang','xiaofang'=>{ # 第三个匿名hash 'gender'=>'female','age' =>19,'prov' =>'fujian',); say "$name[2]"; # 输出HASH(0x...) say "$hash[wugui]"; # 输出HASH(0x...) say "$name[2]{age}"; say "$hash{wugui}{prov}"; 再例如,将一个匿名hash赋值给一个引用变量: $ref_myhash = { name => 'Gilligan',hat => 'White',shirt => 'Red',position => 'First Mate',}; 为了后期维护方便,匿名数组、匿名hash中最后一个元素都使用了逗号。这个逗号并不会影响结果,但是却给未来修改匿名对象带来很大方便。 解除匿名对象的引用从上面实验的结果中可以看到,当输出匿名对象时,其实输出的是个引用。 say "$name[1]"; # 输出ARRAY(0x...) say "$hash{wugui}"; # 输出ARRAY(0x...) say "$name[2]"; # 输出HASH(0x...) say "$hash[wugui]"; # 输出HASH(0x...) 既然是引用,就可以解除引用,还原到数据对象:
例如,解除匿名数组对象,并获取匿名数组中的元素: say "@{ ['longshuai','xiaofang','wugui'] }"; # 解除匿名对象的引用 say "@{ [qw(longshuai xiaofang wugui)] }"; # 解除匿名对象的引用 say "@{ [qw(longshuai xiaofang wugui)] }[1]"; # 获取匿名对象中的第二个元素 解除匿名hash对象,并获取匿名hash中的元素: $ref_hash={ # 构造匿名hash,赋值给引用变量 'longshuai'=> ['male','wugui' => ['male','xiaofang' => ['female',}; @mykeys=keys %{ $ref_hash }; # 通过引用还原到匿名hash say "@mykeys"; # 输出匿名hash中的键 say $ref_hash->{wugui}[2]; # 输出匿名hash中匿名数组的某个元素 再例如,直接在需要hash的地方构建一个匿名hash,并解除引用。 @mykeys=keys %{ # 解除匿名hash { # 构造匿名hash 'longshuai'=> ['male',} }; say %{ # 解除匿名hash { # 构造匿名hash 'longshuai'=> ['male',}; 如何区分匿名hash和一次性代码块匿名hash使用大括号进行构建。但除了匿名hash,大括号还可以用来包围一堆语句,作为只执行一次的语句块。例如: { my $name="longshuai"; my $prov="jiangxi"; } # 出了语句块,上面两个my标记的变量就失效了 那么如何让perl知道大括号是用来构造匿名hash的,还是用来做一次性语句块的?大多数时候,Perl根据上下文的环境会自动判断出来,但是有些时候无法判断,这时可以显式告诉Perl,这是匿名hash的构造符号,还是一次性语句块的符号。
Perl的autovivification特性这个单词,真的无语了,竟然找不到对应的翻译,是perl自造的词。 根据它的功能,我将其大概解释下:当解除引用时,如果解除目标不存在,perl会自动创建一个空目标,而且自动创建时,会自动递归补齐上层。注意,是解除引用时。 这就像unix下的mkdir命令的 例如,下面的示例: #!/usr/bin/perl use 5.010; push @{ $config{path} },'/usr/bin/perl'; say keys %config; # 输出:path say $config{path}; # 输出:ARRAY(0x...) say $config{path}[0]; # 输出:/usr/bin/perl 执行到push的时候,perl首先会发现 在上面的示例中,perl在解除引用时,自建了几个层次:1.自建一个hash对象;2.自建hash对象中的一个元素;3.自建hash对象中某个元素的value部分。 必须注意,perl的autovivification功能只在解除引用的时候才自建,从解除引用的操作动机上看,当要解除引用,说明可能要操作引用对象中的数据了,那么缺少的部分应该要补齐。 如果不是在解除引用,那么perl将根据语法特性决定是否自建对象。例如下面将自建数组 push @name,"longshuai"; $person{name}="longshuai" say "$name[0]"; say keys %person; 紧跟着上面的示例: @{ $config{path} }[2]='/usr/bin/perl'; say $config{path}; # 输出:ARRAY(0x5571664403c0) say $config{path}[0]; # 输出:空 say $config{path}[1]; # 输出:空 say $config{path}[2]; # 输出:/usr/bin/perl say scalar @{$config{path}}; # 输出元素个数:3 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |