$#arrayを事前にインクリメントするとはどういう意味ですか?

StackOverflow https://stackoverflow.com/questions/602451

  •  03-07-2019
  •  | 
  •  

質問

次のコード行に出会いました。問題があります:

  • プッシュと同じことを行うことを意図しています
  • プッシュを使用する必要があります
  • 読みにくく、理解しにくい
  • プッシュを使用するように変更しました
  • 違法だと思ったことがありますが、明らかに違法ではありません

ここにあります:

$array [++$#array] = 'data';

私の質問は、$#arrayを事前にインクリメントすることはどういう意味ですか?私は常に$#arrayは配列の属性であり、書き込み可能ではないと考えていました。

役に立ちましたか?

解決

perldata のコメント:

"配列の長さはスカラー値です。 cshのように$#daysを評価することで、配列@daysの長さを見つけることができます。ただし、これは配列の長さではありません。これは最後の要素の添え字です。通常は0番目の要素があるため、異なる値になります。 $#daysに割り当てると、実際には配列の長さが変わります。この方法で配列を短くすると、介在する値が破壊されます。以前に短縮された配列を延長しても、それらの要素にあった値は復元されません。"

場合によっては$#arrayを変更すると便利ですが、この場合は明らかにpushの方が優れています。

他のヒント

ポストインクリメントは、最初に変数を返し、次に変数をインクリメントします。

ポストインクリメントを使用した場合、最後に返された要素を変更し、最後に空の要素をプッシュします。 2番目のループでは、その空の値を変更し、後で空の値をプッシュします。したがって、プッシュのようにはまったく機能しません。

プリインクリメントは変数をインクリメントしてから返します。そうすれば、例は常に配列の新しい最後の要素に書き込みを行い、プッシュのように動作します。以下の例:

my (@pre, @post);

$pre[$#pre++] = '1';
$pre[$#pre++] = '2';
$pre[$#pre++] = '3';


$post[++$#post] = '1';
$post[++$#post] = '2';
$post[++$#post] = '3';

print "pre keys: ".@pre."\n";
print "pre: @pre\n";
print "post keys: ".@post."\n";
print "post: @post\n";

出力:

pre keys: 3
pre: 2 3
post keys: 3
post: 1 2 3

現在の配列の長さより大きい値を $#array に割り当てると、配列が拡張されます。

このコードも機能します:

$ perl -le 'my @a; $a[@a]="Hello"; $a[@a]=" world!"; print @a'
Hello world!

Perl配列は動的で、制限を超えて割り当てると大きくなります。

まず第一に、それはファウルです。

とはいえ、それが機能することにも驚いています。 ++ $#array が「定数を変更できません」を取得したと推測していました。数値をインクリメントしようとするとエラーが発生します。 (もちろん、私が誤ってそうすることはありません。)しかし、私たちが間違っていたのはまさにそれだと思います。 $#array は定数(数値)ではありません。それは変数式です。そのため、それを台無しにすることができます。以下を考慮してください。

my @array = qw/1 2 3/;

++$#array;
$array[$#array] = qw/4/;

print "@array\n"

さらに、さらに楽しくするために、これ:

my @array = qw/1 2 3/;

$#array += 5;

foreach my $wtf (@array) {
  if (defined $wtf) {
    print "$wtf\n";
  }
  else {
    print "undef\n";
  }
}

そして、ええ、 Perl Cookbook $#array をいじって配列を拡大または切り捨てます(第4章、レシピ3)。私はまだいですが、多分それは長引く「しかし、それは数字です」偏見。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top