6

'空のスロット'を含む配列を作成できます。

$ perl -wde 1
...
  DB<1> $x[2] = 0
  DB<2> x \@x
0  ARRAY(0x103d5768)
   0  empty slot
   1  empty slot
   2  0

また

  DB<3> $#y = 4
  DB<4> x \@y  
0  ARRAY(0x103d5718)
   0  empty slot
   1  empty slot
   2  empty slot
   3  empty slot
   4  empty slot

注意:これは、を割り当てることと同じではありませんundef

[しかし、とを使用して匿名配列にそれを指定するにはどうすればよい]ですか?

これは機能しません:

  DB<5> x [,,0]
syntax error at (eval 27)[/usr/local/lib/perl5/5.10.0/perl5db.pl:638] line 2, near "[,"

そして、これも失敗します。割り当てられた値しか取得できないためです。

  DB<6> x []->[2] = 0
0  0

ボーナスの質問:Perlスクリプトで「空の配列スロット」を確認するにはどうすればよいですか?

背景:私のテストスクリプトでは、配列の内容を正確に比較できるようにしたいと思います。たとえば、「割り当てられていない」と「undef値で割り当てられている」を区別したいと思います。

洞察をありがとう。

4

4 に答える 4

6
use feature qw/ say /;
use strict;
use warnings;

my $aref;

$#{$aref} = 4;
$aref->[2] = undef;
$aref->[3] = '';

foreach my $idx ( 0 .. $#{$aref} ) {
    say "Testing $idx.";
    say "\t$idx exists." if exists $aref->[$idx];
    say "\t$idx defined." if defined $aref->[$idx];
}

OUTPUT:
Testing 0.
Testing 1.
Testing 2.
    2 exists.
Testing 3.
    3 exists.
    3 defined.
Testing 4.

匿名配列に5つのスポットを事前に割り当てました@{$aref}。最上位のインデックスは4です。トップインデックスは、作成したのと同じ方法で見つけることができます。の値をテストすることによって$#{$aref}。存在をテストできます。私たちはその間のすべてを知って0おり、4作成されました。しかし、Perlは、特に何かが割り当てられている配列要素についてのみ「存在する」と報告します(たとえそれが割り当てられている場合でもundef)。したがって、$aref->[2]存在すると報告されますが、定義されていません。楽しみのために、一度定義されたテストレポートを表示するように割り当て''ました。しかし、簡単に言うと、配列が事前拡張されている場合でも、'を使用して、で初期化されている要素と配列の事前拡張を介して$aref->[3]いる要素の違いをテストできます。undefundefexists'。

の文書化された動作とは言えませんexists。したがって、いつか変更されないという保証はありません。ただし、5.8、5.10、5.12、および5.14で動作します。

したがって、どの要素が初期化され、どの要素が定義され、どの要素が定義されていないかを見つける簡単な方法を探して、次に例を示します。

use feature qw/ say /;
use strict;
use warnings;

my $aref;

$#{$aref} = 4;
$aref->[2] = undef;
$aref->[3] = '';

my @initialized = grep { exists $aref->[$_] } 0 .. $#{$aref};
my @defined = grep { defined $aref->[$_] } 0 .. $#{$aref};
my @uninitialized = grep { not exists $aref->[$_] } 0 .. $#{$aref};
my @init_undef = grep { exists $aref->[$_] and not defined $aref->[$_] } 0 .. $#{$aref};
say "Top index is $#{$aref}.";
say "These elements are initialized: @initialized.";
say "These elements are not initialized: @uninitialized.";
say "These elements were initialized with 'undef': @init_undef.";
say "These elements are defined: @defined."
于 2011-07-03T22:44:53.730 に答える
4

それはするべきです:

$a=[];
$#$a=4;

更新(@hexcoderへの返信):1つのステートメントで:

$#{$a=[]}=4

そして、配列を返す1つのステートメントで:

$a = (map(($_,$#$_=4),[]))[0]

ただし、その構造を使用することをお勧めします...

于 2011-07-03T22:27:18.737 に答える
1

背景:私のテストスクリプトでは、配列の内容を正確に比較できるようにしたいと思います。たとえば、「割り当てられていない」と「undef値で割り当てられている」を区別したいと思います。

インデックスが終了を過ぎているかどうかを確認できます。それを超えて、あなたができることはあまりありません。

$x = [];
undef $x->[9999];
print scalar @$x;

10000を出力します。これundef $x->[9999]$x->[9999] = undef;、0から9998までの要素が存在しないため、perlは介在するすべての要素を魔法のようにに割り当てますundef

于 2011-07-03T22:29:10.353 に答える
-1

XSコードからのみそのようなことを行うことができます(たとえばを参照Devel::Peek)。すべてではありませんが、一部はパッケージによって公開されてい*::Utilます。(私はデバッグ/トレースパッケージに取り組んでいるので、誰もが必要とするよりもこれについてもっと知っています...)

于 2011-07-03T22:13:58.150 に答える