Perl匿名数组、hash和autovivification特性
可有構建匿名的對象,這樣就沒必要去為只用一兩次的數組、hash去取名字,有時候取名是很煩的事。
- 使用中括號[]構建匿名數組
- 使用大括號{}構建匿名hash
- 不包含任何元素的[]和{}分別是匿名空數組、匿名空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',['longshuai','wugui','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...)既然是引用,就可以解除引用,還原到數據對象:
- 正常情況下,使用@{數組引用}的方式解除數組引用,使用%{hash引用}的方式解除hash引用
- 所以使用@{匿名數組}解除匿名數組,使用%{匿名hash}解除匿名hash
- 注意,解除正常的數組、hash引用時,可以使用非規范的解除方式(去掉大括號,如@$ref_name),但是解除匿名對象的引用,必須不能去掉大括號
- 訪問匿名對象中的元素和正常對象一樣。一般沒有必要去獲取匿名對象中的元素,但是卻有必要設置匿名對象中的元素時,后面介紹autovivification時將會看到這種行為
例如,解除匿名數組對象,并獲取匿名數組中的元素:
say "@{ ['longshuai','xiaofang','wugui'] }"; # 解除匿名對象的引用 say "@{ [qw(longshuai xiaofang wugui)] }"; # 解除匿名對象的引用 say "@{ [qw(longshuai xiaofang wugui)] }[1]"; # 獲取匿名對象中的第二個元素解除匿名hash對象,并獲取匿名hash中的元素:
$ref_hash={ # 構造匿名hash,賦值給引用變量'longshuai'=> ['male',18,'jiangxi'],'wugui' => ['male',20,'zhejiang'],'xiaofang' => ['female',19,'fujian'], };@mykeys=keys %{ $ref_hash }; # 通過引用還原到匿名hash say "@mykeys"; # 輸出匿名hash中的鍵 say $ref_hash->{wugui}[2]; # 輸出匿名hash中匿名數組的某個元素再例如,直接在需要hash的地方構建一個匿名hash,并解除引用。
@mykeys=keys %{ # 解除匿名hash{ # 構造匿名hash'longshuai'=> ['male',18,'jiangxi'],'wugui' => ['male',20,'zhejiang'],'xiaofang' => ['female',19,'fujian'],}};say %{ # 解除匿名hash{ # 構造匿名hash'longshuai'=> ['male',18,'jiangxi'],'wugui' => ['male',20,'zhejiang'],'xiaofang' => ['female',19,'fujian'], },};如何區分匿名hash和一次性代碼塊
匿名hash使用大括號進行構建。但除了匿名hash,大括號還可以用來包圍一堆語句,作為只執行一次的語句塊。例如:
{my $name="longshuai";my $prov="jiangxi"; } # 出了語句塊,上面兩個my標記的變量就失效了那么如何讓perl知道大括號是用來構造匿名hash的,還是用來做一次性語句塊的?大多數時候,Perl根據上下文的環境會自動判斷出來,但是有些時候無法判斷,這時可以顯式告訴Perl,這是匿名hash的構造符號,還是一次性語句塊的符號。
- 大括號前面加上+符號,即+{...},表示這個大括號是用來構造匿名hash的
- 大括號內部第一個語句前,多使用一個;,即{;...},表示這個大括號是一次性語句塊
+還可以加在匿名數組的中括號前,以及hash引用變量、數組引用變量前,而不僅僅是匿名hash的大括號前,如+$ref_hash、+[]、+$ref_arr。
@{ +[qw(longshuai wugui)]} # 匿名數組中括號前 @{ +$ref_arr } # 數組引用變量前 %{ +$ref_hash } # hash引用變量前Perl的autovivification特性
這個單詞,真的無語了,竟然找不到對應的翻譯,是perl自造的詞,但卻應用到了多種語言中:Wiki Autovivification。
根據它的功能,我將其大概解釋下:當解除引用時,如果解除目標不存在,perl會自動創建一個空目標,而且自動創建時,會自動遞歸補齊上層。注意,是解除引用時。
這就像unix下的mkdir命令的-p選項一樣,當創建某個目錄的時候,如果它的父目錄不存在,就會自動創建。
例如,下面的示例:
#!/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首先會發現@{}在解除一個引用,這個引用是$config{path},是一個hash引用,但是perl發現這個hash不存在,hash里的key(即path)也不存在,而且既然是push操作,說明這個key對應的value是個列表。于是perl的autovivification特性,首先會構建一個空的hash對象%config={},然后創建hash里的一個key:path,其值為空列表,即$config{path}=[],最后將"/usr/bin/perl"這個字符串push到對應的列表中,即$config{path}=['/usr/bin/perl']。
在上面的示例中,perl在解除引用時,自建了幾個層次:1.自建一個hash對象;2.自建hash對象中的一個元素;3.自建hash對象中某個元素的value部分。
必須注意,perl的autovivification功能只在解除引用的時候才自建,從解除引用的操作動機上看,當要解除引用,說明可能要操作引用對象中的數據了,那么缺少的部分應該要補齊。
如果不是在解除引用,那么perl將根據語法特性決定是否自建對象。例如下面將自建數組@name和hash對象%person以及它的一個元素$person{name}。但這不是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 《新程序員》:云原生和全面數字化實踐50位技術專家共同創作,文字、視頻、音頻交互閱讀總結
以上是生活随笔為你收集整理的Perl匿名数组、hash和autovivification特性的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 为什么我们做分布式的使用都是用Redis
- 下一篇: 【Android开发经验】android