[英]understanding data structures in perl
我正在嘗試理解perldsc文檔中的“常見錯誤”部分。 當他提到時,作者試圖傳達的是什么:
構造像數組數組之類的兩個最常見的錯誤是意外地計算元素的數量,或者重復引用相同的內存位置。 在這種情況下,您只需獲取計數而不是嵌套數組:
for my $i (1..10) {
my @array = somefunc($i);
$AoA[$i] = @array; # WRONG!
}
根據我的理解,當它迭代時,它將取第一個值(1..10),它是1,並將它傳遞給這樣的函數:
my @array = somefunc(1);
由於沒有定義該函數,我將創建邏輯。
sub somefunc {
my $a = shift;
print $a * $a;
}
這基本上會這樣做:
1 * 1
結果是'1'。
根據我的理解,我的@array看起來像:
@array = ('1');
下一行將做:
$AoA[$i] = @array;
我假設$ AoA [$ 1]是一個匿名數組(他/她沒有用'my',btw聲明),@ array將是這個匿名數組的第一個元素,作者說它'錯了。 並為每個循環迭代到'2'。
somefunc(2);
這將是'4'並傳遞給:
$AoA[$i] = @array
使用此代碼的作者有什么意義呢? 我試圖理解錯誤,但更重要的是,我正在努力理解代碼。 任何幫助將不勝感激。
UPDATE
我想我明白為什么這是一個常見的錯誤,因為當我使用print和Dumper時,我可以直觀地看到作者試圖傳達的內容,這里是修改后的代碼。
#!/usr/bin/perl -w
use strict;
use Data::Dumper;
for my $i (1..10) {
my @AoA;
my @array = somefunc($i);
print "The array is Dumper(@array)\n";
$AoA[$i] = @array; # WRONG!
print Dumper($AoA[$i]);
}
sub somefunc {
my $a = shift;
return $a * $a;
}
他/她表示,在perldoc perldsc的常見錯誤段落中
在這種情況下,您只需獲取計數而不是嵌套數組:
以下是翻斗車的輸出。
The array is Dumper(1)
$VAR1 = 1;
The array is Dumper(4)
$VAR1 = 1;
The array is Dumper(9)
$VAR1 = 1;
The array is Dumper(16)
$VAR1 = 1;
The array is Dumper(25)
$VAR1 = 1;
The array is Dumper(36)
$VAR1 = 1;
The array is Dumper(49)
$VAR1 = 1;
The array is Dumper(64)
$VAR1 = 1;
The array is Dumper(81)
$VAR1 = 1;
The array is Dumper(100)
$VAR1 = 1;
所以我假設重復了
$VAR1 = 1;
是計數而不是嵌套數組。
作者確實指出,如果計數是我真正想要的,那么就像這樣重寫代碼:
#!/usr/bin/perl -w
use strict;
use Data::Dumper;
for my $i (1..10) {
my @count;
my @array = somefunc($i);
print "The array is Dumper(@array)\n";
$count[$i] = scalar @array;
print Dumper($count[$i]);
}
sub somefunc {
my $a = shift;
return $a * $a;
}
但文檔沒有告訴我如何獲得嵌套數組?
UPDATE
如果我錯了,請糾正我,但我重寫代碼以獲取嵌套數組:
#!/usr/bin/perl -w
use strict;
use Data::Dumper;
my @count;
my @new_array;
for my $i (1..10) {
#my @count;
my @array = somefunc($i);
push @new_array, [@array];
}
sub somefunc {
my $a = shift;
return $a * $a;
}
print Dumper(\@new_array);
哪個印刷
$VAR1 = [
[
1
],
[
4
],
[
9
],
[
16
],
[
25
],
[
36
],
[
49
],
[
64
],
[
81
],
[
100
]
];
在以下聲明中:
$AoA[$i] = @array;
@array
在標量上下文中引用,產生許多元素。 上下文由LHS強加,即$AoA[$i]
,它是@AoA
數組的單個元素。
在Perl中,嚴格意義上沒有數組數組。 它們基本上由“扁平”數組或帶引用的數組模擬。 對於后者,您需要使用take reference運算符,如:
$AoA[$i] = \@array;
對於入門者,您可能會發現, Data::Dumper
在檢查復雜數據結構(如arrayrefs和hashrefs)時非常方便。
Perl是多態的,這意味着它可以透明地處理不同的數據類型,並且通常可以很好地猜測如何處理某些事情。 這使得程序員的工作變得更加容易,因為它不像其他語言那樣強類型化。
因此,例如,如果$ i是數字4,您可以這樣做:
print $i + 1;
你會看到一個5 - 很合乎邏輯,對嗎?
如果你這樣做:
print "I am " , $i , " years old";
您將看到“我已經4歲了” - 在這種情況下,perl說“您正在列表上下文中操作,因此我將$ i視為字符串。無需將該數字轉換為字符串,因為許多其他語言都堅持。
所以當你分配
$AoA[$i] = @array;
它對待這種方式取決於具體情況。 在標量上下文中,它將$ AoA [$ i]設置為數組的長度。
有關標量與列表上下文的更多信息,請閱讀以下答案:
你的例子對於理解這里發生的事情並不是很有用,因為你的子程序總是返回“1” - 調用print()
的結果。 如果用return()
替換print()
,那么你將得到不同的值(1,4,9等)。
但下一行代碼:
$AoA[$i] = @array;
總是將1
分配給@Aoa
的元素。 那是因為你正在為一個標量變量( $AoA[$i]
)分配一個數組( @array
),當你在一個標量上下文中計算一個數組時,你得到了數組中的元素數。
現在,由於你的@array
只有一個元素,你可以這樣做:
$AoA[$i] = $array[0];
但這並不是真正構建一個數組陣列。 你真正想要做的是獲得一個數組的引用。
$AoA[$i] = \@array;
如果子例程返回多個值,這將更有用。
sub somefunc {
# Used $x instead of $a as $a has a special meaning in Perl
my $x = shift;
return ($x * $x, $x * $x * $x);
}
for my $i (1..10) {
my @array = somefunc($i);
$AoA[$i] = \@array;
}
作為探索它的有用工具是Data :: Dumper 。 嘗試添加:
use Data::Dumper;
在您的代碼的頂部和:
print Dumper @AoA;
在foreach
循環之后,查看您獲得的不同數據結構。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.