可有構建匿名的對象,這樣就不必去爲只用一兩次的數組、hash去取名字,有時候取名是很煩的事。數組
[]
構建匿名數組{}
構建匿名hash[]
和{}
分別是匿名空數組、匿名空hash例如,在數組、hash中構建匿名數組:ui
@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()。scala
# 如下等價 @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賦值給一個引用變量:unix
$ref_myhash = { name => 'Gilligan', hat => 'White', shirt => 'Red', position => 'First Mate', };
爲了後期維護方便,匿名數組、匿名hash中最後一個元素都使用了逗號。這個逗號並不會影響結果,可是卻給將來修改匿名對象帶來很大方便。code
從上面實驗的結果中能夠看到,當輸出匿名對象時,其實輸出的是個引用。對象
say "$name[1]"; # 輸出ARRAY(0x...) say "$hash{wugui}"; # 輸出ARRAY(0x...) say "$name[2]"; # 輸出HASH(0x...) say "$hash[wugui]"; # 輸出HASH(0x...)
既然是引用,就能夠解除引用,還原到數據對象:遞歸
@{數組引用}
的方式解除數組引用,使用%{hash引用}
的方式解除hash引用@{匿名數組}
解除匿名數組,使用%{匿名hash}
解除匿名hash@$ref_name
),可是解除匿名對象的引用,必須不能去掉大括號例如,解除匿名數組對象,並獲取匿名數組中的元素:ip
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,大括號還能夠用來包圍一堆語句,做爲只執行一次的語句塊。例如:
{ 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自造的詞,但卻應用到了多種語言中: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