web-dev-qa-db-ja.com

ポストインクリメント演算子がintを返すメソッドで機能しないのはなぜですか?

public void increment(){
    int zero = 0;

    int oneA = zero++; // Compiles

    int oneB = 0++; // Doesn't compile

    int oneC = getInt()++; // Doesn't compile
}

private int getInt(){
    return 0;
}

それらはすべてintですが、なぜB&Cはコンパイルされないのですか? ++演算子が= 0 + 1;と異なる方法と関係がありますか?

操作の引数が無効です++ /-

61
Blundell

_i++_は、変数iへの割り当てです。

あなたの場合、_zero++_は_zero = zero + 1_と同等です。したがって、_0++_は_0 = 0 + 1_を意味しますが、これは意味がなく、getInt() = getInt() + 1も意味します。

より正確に :

_int oneA = zero++;
_

手段

_int oneA = zero;
zero = zero + 1; // OK, oneA == 0, zero == 1
_

_int oneB = 0++;
_

手段

_int oneB = 0;
0 = 0 + 1; // wrong, can't assign value to a value.
_

_int oneC = getInt()++;
_

手段

_int oneC = getInt();
getInt() = getInt() + 1; // wrong, can't assign value to a method return value.
_

より一般的な観点から、変数はL値です。これは、メモリの場所を参照しているため、割り当てることができることを意味します。 [〜#〜] l [〜#〜] in [〜#〜] l [〜#〜]-値は側を表しますL値が代入演算子の左側または右側にある場合でも(たとえば、_=_)、代入演算子の(つまり、_x = y_)。

反対はR値[〜#〜] r [〜#〜]代入演算子の側を表します)。 R値は、L値に何かを割り当てるために、割り当てステートメントの右側でのみ使用できます。通常、R値はリテラル(数値、文字列など)とメソッドです。

147
xlecoustillier

[〜#〜] jls [〜#〜] で述べたように:

後置式の結果は、数値型(§5.1.8)に変換可能な型の変数である必要があります。そうでない場合、コンパイル時エラーが発生します。

29
PermGenError

getInt()intではありません

getInt()intを返します

_++_演算子は2つのことを行いますincrement + assignment

したがって、_++_演算子が機能するには、インクリメント操作の結果を格納する変数が必要ですが、_0_とgetInt()はどちらもそうではありません。

14
Apurv

事前演算子と事後演算子は、呼び出された変数または左辺値のみを操作します。左辺値は左の値の略です。つまり、割り当ての左に立つことができるものです。あなたの例では:

    zero = 1; // OK
    0 = 1; // Meaningless
    getInt() = 1; // Also meaningless

// jk

10
j.karlsson

BとCはどちらも、コンパイラに次のように言わせます。

予期しないタイプ、必須:変数、検出:値

したがって、値をインクリメントすることはできず、変数のみをインクリメントできます。

5
user1907906

ポストインクリメント演算子がintを返すメソッドで機能しないのはなぜですか?

これはゲッターメソッドであり、ゲッターを介して値を変更することは意味がないためです。


int z = x + y++;

と同等です:

int z = x + y;
y = y + 1;

したがって、次のようなものを持つことは無効です。

int z = x + getY()++;

これは次と同等です:

int z = x + getY();
getY() = getY() + 1; // invalid!
4
Eng.Fouad

0 ++

これは0 = 0 + 1;と同等であり、確かに不可能です。

つまり、割り当てるにはl-valueである必要があります。

getInt()++;

ここで同様の理由。

3
Azodious

なぜなら0rValueです(つまり、代入演算子の右側からのみ使用できます)not a lValue

++演算子は値をインクリメントし、それ自体に設定するため、0++エラーが発生します。

2
Arsen Alexanyan

私の答えは、そのような「箱から出して」です。

演算子の使用法に疑問がある場合、この演算子の「オーバーロードされた関数はどれに相当するか」と思いますか?

Java演算子には演算子のオーバーロードがなく、解決策を作成するための代替方法にすぎないことを私は知っています。

この場合:

...
x++;
...

次のように読む必要があります:

...

int /* function */ postincrement (/* ref */ int avalue)
{
  int Result = avalue;

  // reference value, 
  avalue = avalue + 1;

  return Result;
}

...
postincrement(/* ref */ x);
...

そして:

...
++x;
...

...

int /* function */ preincrement (/* ref */ int avalue)
{
  // reference value, 
  avalue = avalue + 1;

  int Result = avalue;

  return Result;
}

...
preincrement(/* ref */ x);
...

したがって、両方のバージョンの「++」は、参照によって変数パラメーターを受け取る関数として機能します。

したがって、「0 ++」のようなリテラル値または「getInt()++」のような関数結果は、変数参照ではありません。

乾杯。

0
umlcat

関数の戻りはRHS式であるため、前後のインクリメント/デクリメント操作はLHS式にのみ適用できます。

0
Gaurav Phapale

postincrementとpreincrementは、変数を使用した場合にのみ適用できます。したがって、最初のケースはコンパイルされます。

0
Gijo