5

コードを考えると:

my $x = 1;

$x = $x * 5 * ($x += 5);

私は次のよう$xになると思います180

$x = $x * 5 * ($x += 5); #$x = 1
$x = $x * 5 * 6;         #$x = 6
$x = 30 * 6;
$x = 180;
180;

しかし、そうではあり30ません。ただし、用語の順序を変更すると、次のようになります。

$x = ($x += 5) * $x * 5;

私は得180ます。私が混乱している理由は、それperldoc perlopが非常にはっきりと言っているからです:

Perl では TERM が最も優先されます。それらには、変数、引用符および引用符のような演算子、括弧内の式、および引数が括弧で囲まれている関数が含まれます。

は括弧内にあるため($x += 5)、項である必要があり、式の順序に関係なく最初に実行されます。

4

4 に答える 4

16

質問を入力するという行為は、私に答えをもたらしました:用語は最も優先順位が高い. つまり$x、コードの最初のチャンクの が評価されて yieldされ、次にが評価されて yieldされ、次に1が評価されて得られます( に設定する副作用があります):55($x += 5)6$x6

$x = $x * 5 * ($x += 5);
address of $x = $x * 5 * ($x += 5); #evaluate $x as an lvalue
address of $x = 1 * 5 * ($x += 5);  #evaluate $x as an rvalue
address of $x = 1 * 5 * ($x += 5);  #evaluate 5
address of $x = 1 * 5 * 6;          #evaluate ($x += 5), $x is now 6
address of $x = 1 * 5 * 6;          #evaluate 1 * 5
address of $x = 5 * 6;              #evaluate 1 * 5
address of $x = 30;                 #evaluate 5 * 6
30;                                 #evaluate address of $x = 30

同様に、2 番目の例は次のように縮小されます。

$x = ($x += 5) * $x * 5; 
address of $x = ($x += 5) * $x * 5; #evaluate $x as an lvalue
address of $x = 6 * $x * 5;         #evaluate ($x += 5), $x is now 6
address of $x = 6 * 6 * 5;          #evaluate $x as an rvalue
address of $x = 6 * 6 * 5;          #evaluate 5
address of $x = 36 * 5;             #evaluate 6 * 6
address of $x = 180;                #evaluate 36 * 5
180;                                #evaluate $x = 180
于 2009-11-05T17:46:14.967 に答える
9

このようなことについて混乱するときはいつでも、最初にperldoc perlopを引き出します。それでもわからない場合、または特定のコードブロックがどのように実行されるかを確認したい場合は、B::Deparseを使用します:

perl -MO=Deparse,-p,-q,-sC
my $x = 1;
$x = $x * 5 * ($x += 5);

^D

与えます:

(my $x = 1);
($x = (($x * 5) * ($x += 5)));
- syntax OK

したがって、各段階で値を代入すると、次のようになります。

($x = (($x * 5) * ($x += 5)));
($x = ((1 * 5) * ($x += 5)));
($x = ((5) * (6))); # and side-effect: $x is now 6
($x = (5 * 6));
($x = (30));
($x = 30);
$x = 30;

したがって、$x が一時的に 6 に設定されたという事実は、実際には何も影響しません。なぜなら、以前の値 (1) は既に式に代入されており、式の終わりまでに 30 になっているからです。

于 2009-11-05T18:17:55.853 に答える
4

$xそれ自体も TERM です。(最初の例で)最初に遭遇したため、最初に評価されます。

于 2009-11-05T18:03:49.503 に答える
2

演算子の結合性*は左向きであるため、常に左端の項が右端の項の前に評価されます。などの他の演算子**は右結合で($x += 5)あり、ステートメントの残りの部分の前に評価されます。

于 2009-11-05T21:16:47.320 に答える