2012-10-31 62 views
2

我想以我能理解的各種方式使用對數組的引用。
這裏是我的審判之一: -使用對匿名數組的引用作爲數組的一個元素

my $RoR = [[2, 3], [4, 5, 7]]; 
my @AoA = ([2, 3], [[2, 3], [4, 5, 7]]); 
my @AwR = ([2, 3], @{$RoR}); 

print $AoA[1][1][1], "\n";  # 1 
print $AoA[1]->[1][1], "\n"; # 2 

#print $RoR[0][1], "\n";  # 3 
print $RoR->[0][1], "\n";  # 4 

print $AwR[1][1][1], "\n";   # 5 
print $AwR[1]->[1][1], "\n";  # 6 

正如你所看到的,我有三個不同的陣列。

  • $RoR - >是一個匿名陣列,它包含兩個匿名數組

  • @AoA基準 - >是含有2匿名數組的數組。第二匿名陣列是相同陣列由參考$RoR

  • @AwR指向 - >幾乎是相同@AoA,但是,而不是一個新的匿名陣列,我已經添加了參考@{$RoR}本身的差異,在裏面。所以,基本上我認爲,最後兩個陣列幾乎是一樣的。現在

,問題是,他們沒有以同樣的方式行爲。

  • 打印報表1,並且2工作正常,並打印出來作爲結果的值5

  • 打印語句3是給出錯誤,我知道爲什麼,所以沒有問題。按預期打印語句4正在打印值3

  • 現在,打印語句56在嘗試運行該程序時會拋出一些錯誤。

    "Can't use string ("2") as an ARRAY ref while \"strict refs\" in use at 
    D:/_Perl Practice/3perldsc/array_of_array.pl line 15." 
    

然後我試着使用: -

print $AwR[1][1]->[1], "\n";  
print @{$RoR}[1]->[1]; 

在哪裏,我換成$AwR[1]@{$RoR},爲$AwR[1]包含@{$RoR}。第二個工作正常,而第一個仍然在拋出錯誤。

那麼,1st twolast two打印語句之間究竟有什麼區別?我認爲它們是相同的,因此應該對相同的索引訪問給出相同的結果。但事實並非如此。我是否以某種錯誤的方式使用該參考?


好的,現在上面的疑問很清楚。所以,我發佈了一個答案,積累了與這個問題有關的一般東西。請看下面的內容。在這方面,我在5th and 6th print語句疑問,並瞭解它我嘗試了以下測試: -

print $AwR[1][1]; # Allowed as `$AwR[1]` is same as `$$RoR`. 
print $$RoR[1];  # Allowed as in 3(b) 
print $AwR[1]->[1]; # Confused here. It is allowed 
print $$RoR->[1]; # But this is not. 

前三聲明打印相同reference value。但最後一個失敗。所以,它確信: - $AwR[1]$$RoR相同。但是,爲什麼$$RoR->[1]不工作,而$AwR[1]->[1]正在工作?它扔我這個錯誤: -

Not a SCALAR reference at D:/_Perl Practice/3perldsc/array_of_array.pl line 24. 

那麼,以兩種不同的方式使用它有什麼區別?

+0

我可以推薦優秀的文檔['perldoc perlreftut'](http://p3rl.org/reftut),它真的幫助我學習這些東西! –

+0

@JoelBerger。謝謝你,但我只是從中學習。我發佈了這個例子,只有在理解文檔後才知道.. :( –

回答

5

在assignement到@AwR取消引用您的參考匿名數組$RoR,讓您得到basicly此行爲:

my @AwR = ([2, 3], [2, 3], [4, 5, 7]); 

不期望:

my @AwR = ([2, 3], [[2, 3], [4, 5, 7]]); 

UPDATE

如果我們有多維數組(數組數組,AoA),然後每個維a首先必須是一個參考。所以不需要明確地使用解引用箭頭,但它是允許的。所以,如果我們有AoA作爲參考,我們需要提領第一個維度explicilty,我們可以做兩種方式$$AoA$AoA->,但我們不能解引用它的兩倍,你注意到了(在你的例子$$RoR->[1])。

以下任何尺寸,我們可以省略解引用箭頭,當我們需要解決的某些元素,所以有兩個相同的使用:

my @AoA = ([2, 3], [ [2, 3], [4, 5, 7, [11, 12, [111, 112] ] ] ], [0]); 
print "A: $AoA[1][1][3][2][0] \n";   # == 111 
print "B: $AoA[1]->[1]->[3]->[2]->[0] \n"; # == 111 

AoA作爲參考

my $AoA = [ [2, 3], [ [2, 3], [4, 5, 7, [11, 12, [111, 112] ] ] ], [0] ]; 
print "A: $$AoA[1][1][3][2][0] \n";   # == 111 
print "B: $AoA->[1]->[1]->[3]->[2]->[0] \n"; # == 111 
+0

謝謝。不知道爲什麼,當我嘗試使用'$ RoR'時,出現了一些錯誤,所以我改爲'@ {$ RoR}'。然後我又試了'$ RoR',發現我錯誤,因爲我正在像這樣訪問它: - 'print $ {$ RoR} - > [1] [1]'。 '$ AwR [1]'在'print $ AwR [1] - > [1] [1]中用'$ RoR'''但是我不是。對我來說太愚蠢了。:(再次感謝:) –

+0

@wk你好,請你再看一下我的帖子,我有一個疑問,並在這裏發佈。我沒有創建一個新的問題,因爲它只與這個有關。 –

+0

@RohitJain:我更新了我的答案,希望它能夠清楚地表明 –

3

看來,你期待@AoA和@AwR是相同的,他們不是。你可以用一個簡單的測試腳本來看到這一點:

#!/usr/bin/perl 

use strict; 
use warnings; 
use Test::More; 

my $RoR = [[2, 3], [4, 5, 7]]; 
my @AoA = ([2, 3], [[2, 3], [4, 5, 7]]); 
my @AwR = ([2, 3], @{$RoR}); 

is_deeply(\@AwR, \@AoA, 'arrays match'); 

這是因爲你將$ RoR插入@AwR的方式。爲了不提領$回報率創造相同@AoA創建@AwR數組:

my @newAwR = ([2, 3], $RoR); 

和測試,以確認這是正確的:

is_deeply(\@newAwR, \@AoA, 'arrays match'); 
+0

感謝您的測試@nickisfat。真的很有幫助。現在知道我出錯了。 :) –

+0

@nickisfat ..你好,請你再看看我的帖子。我有一個疑問,並在這裏發佈。我沒有創建一個新的問題,因爲它僅與此相關。 –

1

好了,現在我把它有點清楚,我想我會寄我有一個答案: -

use strict; 
use warnings; 
use Test::More; 

my $RoR = [[2, 3], [4, 5, 7]]; 
my @AoA = ([2, 3], [[2, 3], [4, 5, 7]], [0]); 
my @AwR = ([2, 3], $RoR, [0]); 

print "1: ", $AoA[1][1][1], "\n";  # 1 
print "2: ", $AoA[1]->[1][1], "\n";  # 2 

#print "3(a): ", $RoR[0][1], "\n";  # 3(a) 
print "3(b): ", $$RoR[0][1], "\n";  # 3(b)   
print "4: ", $RoR->[0][1], "\n";  # 4 

print "5: ", $AwR[1][0][1], "\n";  # 5 
print "6: ", $AwR[1]->[0][1], "\n";  # 6 

print "7: ", $AwR[1][1]->[1], "\n";  # 7 
print "8: ", @{$RoR}[1]->[1], "\n";  # 8 
print "9: ", @{$AwR[1]}[1]->[1], "\n"; # 9 

說明: -

  • 前兩個打印語句很簡單。它們都將打印值5
  • 圖3(a)將不編譯,因爲我們無法沒有arrow訪問參考匿名數組的索引。
  • 圖3(b)的作品,因爲現在,我們已經取消引用我們reference - $RoR使用$$RoR

  • 4 print語句,類似於3(b),並且是做什麼3(b)是做了明確的方法。由於RoR是對匿名數組的引用,所以我們無法像普通數組那樣訪問元素。我們必須使用箭頭(->)。在arrow之後,我們可以將索引添加到任何級別以訪問嵌套的anonymous數組。

$$RoR[0][1]作品,因爲$RoR結合更緊密的去參考進行$左側,而不是在subscript運營商在右側。因此,第一個$RoR被取消引用以獲取該數組,然後應用subscript

下面是來自Perl文檔報價: -

Perl's precedence rules on its five prefix dereferencers(which look like someone swearing: $ @ * % &) make them bind more tightly than the postfix subscripting brackets or braces.
The seemingly equivalent construct in Perl, $$aref[$i] first does the deref of $aref, making it take $aref as a reference to an array, and then dereference that, and finally tell you the i'th value of the array pointed to by $AoA

  • 第五和第六打印語句類似於圖3(b)。由於$AwR[1]僅包含參考$RoR。所以,$AwR[1]被轉換爲:$$RoR。因此,$AwR[1][0][1]與第5條陳述中的$$RoR[0][1]類似。第6條陳述: - $AwR[1]->[0][1]被轉換爲: - $$RoR->[0][1]。這是我的疑問。 6th聲明如何工作。爲什麼我們可以在de-referenced reference上使用an arrow

  • 7th print statement,$AwR[1][1]->[1]${$RoR}[1]->[1]類似。所以很顯然,在下標操作符之前完成解引用。因此,我們可以訪問de-referencing參考$RoR後獲得的陣列上的2nd元素。

  • 8th9th print語句都相當一致。還有,我們正在參考reference $RoR。但是現在,我們是de-referencingarray而不是scalar


我試圖在我可以在最好的解釋。如果在上面的解釋中有什麼錯誤或缺失,請指出。這將幫助我學習更多。

另外,有人可以解釋5th6th打印聲明。我會在上面的問題中加上這個。

相關問題