8

これはばかげた質問かもしれません...次のコードはそれぞれ@arrayrefとの内容を出力し@arraycontます。それらの違いと、それらの値が割り当てられる方法に注意してください。匿名配列が何をするかは知っていますが、なぜ違いがあるのか​​誰かが説明できますか?

どうもありがとうございます。

@arrayref = ();
@array = qw(1 2 3 4);
$arrayref[0] = \@array;
@array = qw(5 6 7 8);
$arrayref[1] = \@array;
print join "\t", @{$arrayref[0]}, "\n";
print join "\t", @{$arrayref[1]}, "\n";

@arraycont = ();
@array = qw(1 2 3 4);
$arraycont[0] = [@array];
@array = qw(5 6 7 8);
$arraycont[1] = [@array];
print join "\t", @{$arraycont[0]}, "\n";
print join "\t", @{$arraycont[1]}, "\n";

出力

5   6   7   8   
5   6   7   8   
1   2   3   4   
5   6   7   8   
4

3 に答える 3

11

これにより、配列の浅いコピーが作成されます。

$arraycont[0] = [@array];

これはそれへの参照を作成するだけですが:

$arrayref[0] = \@array;

後でアレイを変更するので:

@array = qw(5 6 7 8);

arrayref引き続きメモリ内の同じ配列位置を指しているため、printステートメントで逆参照されると、現在の配列値が出力されます5 6 7 8

于 2012-05-01T04:27:25.127 に答える
3

最初のブロックには、@arrayのアドレスが格納されます。参照は「ライブストリーミング」のようなもので、現在のステータスを取得します。したがって、\ @ arrayのように@arrayへの参照を作成する場合、それを参照解除すると、参照解除の時点で@arrayが指すものが常に取得されます。参照を解除すると、 @ array(5 6 7 8)を持っていました

[@array]を実行すると、ライブストリーミングをディスクに記録するようなものになります。したがって、記録されたコンテンツを(再)再生すると、記録時にストリーミングされたものが得られます。したがって、$ arraycont [0]を参照すると、コピー時に@arrayが持っていたもの、つまり
(1 2 3 4)が得られます。

于 2012-05-01T07:44:04.340 に答える
0

$arrayref[0]との両方で単一の配列への保存された参照を作成しました$arrayref[1]。別の配列を使用する必要がありました。

my @refs;

my @array1 = qw(1 2 3 4);
push @refs, \@array1;

my @array2 = qw(5 6 7 8);
push @refs, \@array2;

実際にmyは、はループの各パスで実行され、毎回新しい配列を作成します。

my @refs;
while ( my @row = get() ) {
   push @refs, \@row;
}

まれに、アレイのクローンを作成する必要がある場合は、次を使用できます。

use Storable qw( dclone );

push @refs, [ @row ];       # Shallow clone
push @refs, dclone(\@row);  # Deep clone
于 2018-06-18T20:06:38.387 に答える