このページでは、配列を初期化する方法を示しています。少し下にスクロールすると、「リスト」というセクションの下で、リストとは何か、配列とどのように異なるのかが「説明」されています。
ただし、配列の宣言とまったく同じ例を使用しており、それについてはまったく説明していません。
違いはなんですか?
実際、この質問はPerl の FAQでよく答えられています。リストは、Perl ソース コード内のデータを整理する (の 1 つの) メソッドです。配列は、データを格納するタイプの1 つです。ハッシュは別のものです。
違いはここで非常に明白です:
my @arr = (4, 3, 2, 1);
my $arr_count = @arr;
my $list_count = (4, 3, 2, 1);
print $arr_count, "\n"; # 4
print $list_count; # 1
一見すると、ここには 2 つの同一のリストがあります。ただし、@arr
変数に割り当てられたものだけがスカラー代入によって正しくカウントされることに注意してください。$list_count
ストアは 1 - 演算子を使用して式を評価した結果です(comma
基本的に、その列挙の最後の式 - 1 が得られます)。
リスト演算子/関数と配列演算子の間には、わずかな (しかし非常に重要な) 違いがあることに注意してください。前者はソース データを変更しないため、一種の雑食動物ですが、後者はそうではありません。たとえば、次のようにリストを安全にスライスして結合できます。
print join ':', (4,2,3,1)[1,2];
...しかし、「ポップ」しようとすると、非常にわかりやすいメッセージが表示されます。
pop (4, 3, 2, 1);
### Type of arg 1 to pop must be array (not list)...
配列は変数の一種です。単調に増加するインデックスで 0 以上のスカラーを含みます。たとえば、次は array を作成します@a
。
my @a;
変数であるため、配列を操作できます。要素を追加したり、要素の値を変更したりできます。
「リスト」には多くの意味があります。その 2 つの主な用途は、リスト値とリスト演算子のインスタンスを参照することです。
リスト値は、スタック上の 0 個以上のスカラーの順序付けられたコレクションです。たとえば、次のコードの sub は、割り当てられるリスト@a
(配列) を返します。
my @a = f();
リストの値は操作できません。それらは、渡されたすべてのオペレーターによって完全に吸収されます。これらは、サブとオペレーターの間で値が渡される方法です。
リスト演算子 ( ,
) は、各オペランドを順番に評価する N 項演算子* です。リスト コンテキストでは、リスト演算子は、そのオペランドによって返されるリストの合併から構成されるリストを返します。たとえば、次のスニペットの list 演算子は、配列@a
andのすべての要素で構成されるリスト値を返し@b
ます。
my @c = ( @a, @b );
(ちなみに、括弧はリストを作成しません。優先順位をオーバーライドするために存在します。)
コードであるため、リスト演算子を操作することはできません。
* — ドキュメントでは、(少なくともスカラー コンテキストでは) 二項演算子であると書かれていますが、そうではありません。
違いの簡単なデモンストレーション。
sub getarray{ my @x = (2,4,6); return @x; }
sub getlist { return (2,4,6); }
今、あなたがこのようなことをすると:
my @a = getarray();
my @b = getlist();
次に@a
、@b
と の両方に同じ値 ( list ) が含まれます(2,4,6)
。ただし、これを行う場合:
my $a = getarray();
my $b = getlist();
次に$a
、値 3$b
が含まれ、値 6 が含まれます。
そうです、配列はリスト値を含む変数であると言うことができますが、配列とリテラル リストは時々まったく異なる動作をするため、それがすべてを物語っているとは言えません。
リストはカンマ区切り値 (csv) または式 (cse) です。配列 (およびハッシュ) はコンテナーです。
リストによって配列またはハッシュを初期化できます。
@a = ("profession", "driver", "salary", "2000");
%h = ("profession", "driver", "salary", "2000");
リストを返すことができます:
sub f {
return "moscow", "tel-aviv", "madrid";
}
($t1, $t2, $t3) = f();
print "$t1 $t2 $t3\n";
($t1, $t2, $t3) は、スカラー コンテナー $t1、$t2、$t3 のリストです。
リストは perl 式 (構文の一部) を記述する形式であり、配列はデータ構造 (メモリ位置) です。
リストと配列の違いは、多くの人を混乱させます。Perl 自体が、組み込み関数wantarray()の名前を誤って間違っていました: 「この関数は代わりに wantlist() と名付けるべきでした。」perlfaq4 に「リストと配列の違いは何ですか?」という回答があります。、しかし、それは私の混乱を終わらせませんでした。
私は今、これらが真実であると信じています:
\(2, 4, 6)
リスト内のスカラーへの参照のリストを返します。[2, 4, 6]
無名配列への参照を作成するために使用できます。(2, 4, 6)[1]
番目の要素を取得するため)。しかし、リスト内の要素を数えたい場合や、配列の最後の要素を取得したい場合はどうすればよいでしょうか? どうにかして配列とリストを変換する必要がありますか?
構文を使用して、いつでもリストを配列に変換[...]
できます。リスト内の要素を数える 1 つの方法は、無名配列を作成し、次のようにスカラー コンテキストですぐに逆参照することです。
sub list { return qw(carrot stick); }
my $count = @{[list()]};
print "Count: $count\n"; # Count: 2
もう 1 つの方法は、次のようにリスト代入演算子を使用することです。
sub list { return qw(carrot stick); }
my $count = (()=list());
print "Count: $count\n"; # Count: 2
このコードには配列はありませんが、リスト代入演算子は代入されているものの数を返します。それらを変数の空のリストに割り当てます。コード ゴルフでは、()=$str=~/reg/g
文字列内の正規表現の一致をカウントするように記述します。
リストコンテキストの配列はすでにリストであるため、配列をリストに変換する必要はありません。配列の最後の要素が必要な場合は、単に$array[-1]
.
コンマ演算子はリストの最後の要素を返しますが、それを使用して配列の最後の要素を取得することはできません。((),@array)
スカラー コンテキストで言うと、スカラー コンテキストで@array
カウントを取得します。
リストにインデックスを付けるために配列を作成する必要はありません。のように無名配列を作成し[list()]->[1]
たり、 のようにリスト スライスを作成したりできます(list())[1]
。リストスライスは構文が異なるため、問題がありました。リスト スライスには括弧が必要です。C または Python または Ruby ではfunc()[1]
、関数の戻り値に配列インデックスを実行しますが、Perl ではfunc()[1]
構文エラーです。あなたは言わなければなりません(func())[1]
。
たとえば、配列で 3 番目に大きい数値を出力したいとします。私は怠け者なので、配列を並べ替えて、最後の 3 番目の要素を取得します。
my @array = (112, 101, 114, 108, 32, 104, 97, 99, 107);
print +(sort { $a <=> $b } @array)[-3], "\n"; # prints 108
単項+
は、print() 関数が括弧を盗むのを防ぎます。
のように、配列でリスト スライスを使用できます(@array)[1]
。配列はリストであるため、これは機能します。リストと配列の違いは、配列ができることです$array[1]
。
しかし、主な違いは次のとおりです。
配列にはscalar-context-value
likeがありcount of elements
ます。
リストにはscalar-context-value
likeがありLAST element in list
ます。
goat-operator
したがって、 :について知っておく必要があります=()=
。
使用法?
perl -e '$s =()= qw(a b c); print $s' # uh? 3? (3 elements, array context)
perl -e '$s = qw(a b cLastElementThatYouSee); print $s' # uh? cLastElementThatYouSee? (list context, last element returned)
ご覧のとおり、=()=
コンテキストを次のように変更しますarray