web-dev-qa-db-ja.com

Perl配列とリスト

Perlには2つのデータ構造があります。

配列:

my @array2 = ( "1", "2", "3");

for $elem (@array2) {
    print $elem."\n";
}

次の出力を提供します。

1
2
3

そしてリスト:

my @array = [ "1", "2", "3"];                                            

for $elem (@array) {
    print $elem."\n";
}

次の出力を提供します。

ARRAY(0x9c90818)

明らかに、両方の場合で要素を反復処理したいのですが、なぜ2番目の解決策がこの配列への参照のみを提供するのですか?

39
Marcin Cylke

Perlのリストはデータ構造ではなく、ソースコード内の位置であり、周囲のコンテキストによって決定されます。リストは基本的に、Perlがデータを移動するために使用する一時的な構造です。 Perlのすべての構文でそれらと対話しますが、データ型としてそれらを操作することはできません。リストに最も近いデータ型は配列です。

my @var    =    (1, 2, 3);  # parens needed for precedence, they do not create a list
   ^ an array    ^ a list

say 1, 2, 3;
    ^ a list

say @var;
    ^ a list (of one array, which will expand into 3 values before `say` is called)

[1, 2, 3]を記述するとき、あなたがしていることはスカラー配列参照を作成することです。その配列参照はリスト1, 2, 3で初期化され、名前付き配列を作成して参照するのと同じです:

[1, 2, 3]   ~~   do {my @x = (1, 2, 3); \@x}

[...]構文はスカラーを作成するため、スカラーに保持する必要があります。

my $array = [1, 2, 3];                                            

for my $elem (@$array) {   # lexical loop variable
    print $elem."\n";
}

参照だけでなく配列全体を操作するため、@$arrayの前に配置して、保存された配列参照を逆参照します。

80
Eric Strom

角括弧は、匿名配列を作成するために使用されます。評価されると、実際の配列値ではなく、この配列への参照を返します。

括弧にはそのような隠しプロパティはありませんが、数学のように、式の内部で単に precedence をオーバーライドします。例えば:

my @array = 1,2,3;

実際に次のように評価されます:

my @array = 1;
2,3; # causes the warning "Useless use of constant in void context"

=演算子はコンマよりも優先順位が高いためです。そのため、配列を割り当てる際には、次のように括弧を使用します。

my @array = (1,2,3);

あなたの例:

my @array = [1,2,3];

これは幾分こう言っているようなものです:

my @tmp = (1,2,3);
my @array = \@tmp;

\は、@tmp配列への参照を作成するために使用されます。

32
TLP

角括弧は、匿名配列を作成し、配列に角括弧の内容を入力し、その配列への参照を返します。言い換えると、

[ "1", "2", "3" ]

基本的にと同じです

do { my @anon = ("1", "2", "3"); \@anon }

したがって、コードは次のようになります

my $array_ref = [ "1", "2", "3" ];

for (@$array_ref) {  # Short for @{ $array_ref }
    print "$_\n";
}

または

my @array_of_refs = ([ "1", "2", "3" ]);

for my $array_ref (@array_of_refs) {
    for (@$array_ref) {
        print "$_\n";
    }
}
7
ikegami

さらに明確にしたい場合は、 関連ドキュメント を参照してください。

説明のためにいくつかのことを試してみてください:

#!Perl -lw # -l appends a \n to each print, -w enables warnings
use strict;
my $aryref = [1 .. 5];
print for $aryref;    # Prints the stringified reference - not what you want
print for @$aryref;   # Dereferencing it lets you access the array
my @ary = $aryref;    # Probably not what you want
print for @ary;       # Stringified reference again
print for @{$ary[0]}; # Dereference the first array element (which holds the ref)
4
Lumi

@ array =( "1"、 "2"、 "3");ここで、1,2,3は@array変数の要素です。例えば$ array [0]は1、$ array [1]は2、$ array [2]は3です。

@ array = ["1"、 "2"、 "3"]; Perlは[]を使用して匿名の配列参照を使用するため、ここでは基本的に1つの要素のみを格納します。 @array変数への配列["1"、 "2"、 "3"]。 ex for $ array [0] is "ARRAY(0x9c90818)"
したがって、印刷中に参照が表示されます。

0
Sandeep_black

Perlでは、配列とリストは本質的に同じものですが、2番目の例ではどちらも使用していません。角括弧は配列を囲みます参照(スカラー値)、および_my @array = $scalar_のようなものでスカラーを配列に「割り当てる」ことはmy @array = ($scalar)と同等です。したがって、2番目の例の_@array_の唯一の要素は配列参照です。

0
jwodder