簡體   English   中英

了解perl中的數據結構

[英]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]設置為數組的長度。

有關標量與列表上下文的更多信息,請閱讀以下答案:

http://perl.plover.com/context.html

你的例子對於理解這里發生的事情並不是很有用,因為你的子程序總是返回“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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM