2010-05-27 42 views
4

考慮這個Perl代碼我該如何推理這個Perl數組數組?

my @a=[[1]]; 

print $a[0][0]; 


**output** 
ARRAY(0x229e8) 

爲什麼它打印的ARRAY代替1?我期望@a創建一個大小爲1的數組,並引用僅包含一個元素的第二個數組1

+0

可能的重複:http://stackoverflow.com/questions/2860422/what-does-it-mean-when-you-try-to-print-an-array-or-hash-using-perl-and-你得到/ 2860572#2860572 – Zaid 2010-05-28 06:00:08

回答

14

這東西很棘手。您已將@a分配爲一個列表,其中包含對包含對數組的引用的數組的引用,該引用比您期望的要多出一個額外的間接級別。

要獲得期望的結果,你應該說

@a = ([ 1 ]); 
11

您需要的值是$a[0][0][0]。您將數組參考作爲@a數組的第一個元素。

這是一個類似的事情:

my @a = 'scalar'; 

而這將產生1個時隙的陣列以字符串'scalar'作爲唯一的元件。所以,當你爲數組分配一個標量時,Perl試圖按照你想要的來做它的聲音,並創建一個大小爲1的列表,標量值作爲第一個元素。

此外,

my @a = undef; 

做同樣的事情,但是第一個插槽undef。你想要的是

my @a = [1]; 
+0

+1,這個答案回答**爲什麼**! – neevek 2013-05-22 11:28:48

4

這裏是我猜你想寫:

my $x = [[1]]; # reference to anon array containing 
       # reference to anon array with one element 

print $x->[0][0]; 

Perl Data Structures Cookbook見。

+0

我知道這不是特別重要,但'$ x - > [0] - > [0]'是我的首選方式。 – 2010-05-28 02:34:36

+0

@Dan Beam:你爲什麼要這樣做?請參閱http://stackoverflow.com/questions/2475042/nested-dereferencing-arrows-in-perl-to-omit-or-not-to-omit – Zaid 2010-05-28 05:58:02

+0

,因爲對數組和數組refs只使用'[]'可以導致混淆,但正如我所說 - 這並不重要 – 2010-06-02 04:01:17

3

mobrule,斧頭兵和思南都回答了你的問題:你創建的,而不是2

我很驚訝,沒有人使用核心Data::Dumper庫來幫助理解數據結構的問題,提出了一個數據結構3層深, 。

use Data::Dumper; 

my @a = [[1]]; 
print Dumper \@a; 

此打印:

$ VAR1 = [ [ [] ] ];

您的錯誤是使用數組引用構造函數[]而不是僅使用括號(或不使用括號)。 @a = ([1]);

那麼,爲什麼Perl有奇怪的[]{}語法來聲明散列和數組引用?

這歸結於Perl扁平列表的事實。這意味着如果您說:@a = (@b, @c);@a被分配@b的內容連接@c的內容。這與Python的extend列表方法相同。如果你想@a有兩個元素,你需要強制他們不要擴大。你通過參考每個數組來做到這一點:@a = (\@b, \@c);。這就像Python的append列表方法。

當你想創建匿名嵌套結構時,你需要有一種方法將它們標記爲散列或數組。這就是我上面提到的語法。

但是列表展平有什麼好處?爲什麼值得使用這種不尋常的語法來創建數組和散列引用,這與用於正常初始化的語法截然不同?

列表展平意味着您可以輕鬆地將一個子例程參數列表組裝到一個變量中,然後通過它們而不需要執行任何棘手的操作:foo(@some_args, 5, @more_args);。有關此概念如何在其他語言中工作的信息,請參閱Apply on wikipedia。你可以用map和其他功能做各種其他好東西。