java - una - ¿Por qué el operador de incremento incremental no trabaja en un método que devuelve un int?
operadores de incremento y decremento en javascript (11)
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;
}
Todos son int, ¿por qué no compilará B & C? ¿Tiene que ver con la forma en que el operador ++
difiere de = 0 + 1;
?
Argumento no válido para la operación ++ / -
¿Por qué el operador de incremento incremental no trabaja en un método que devuelve un int?
Porque es un método getter, y no tiene sentido cambiar un valor a través de getter.
int z = x + y++;
es equivalente a:
int z = x + y;
y = y + 1;
entonces no es válido tener algo como:
int z = x + getY()++;
que es equivalente a:
int z = x + getY();
getY() = getY() + 1; // invalid!
0 ++
Es equivalente a 0 = 0 + 1;
y ciertamente no es posible.
es decir, tiene que ser l-value
para asignarle.
getInt () ++;
Razón similar aquí.
Como 0
es un valor rValue
(es decir, puede usarlo solo desde la derecha del operador de asignación) not a lValue
.
++
operador incrementa el valor y lo establece a sí mismo, por lo tanto 0++
le dará un error.
Como el retorno de la función es la expresión RHS y las operaciones de incremento / decremento previo / posterior se pueden aplicar solo a las expresiones LHS.
Los operadores previos y posteriores solo operan en variables o valores l a medida que se llaman. lvalue es la abreviatura de valor a la izquierda, es decir, algo que puede pararse a la izquierda en una tarea. En tu ejemplo:
zero = 1; // OK
0 = 1; // Meaningless
getInt() = 1; // Also meaningless
// jk
Mi respuesta es tipo de "fuera de la caja".
Cuando tengo dudas sobre el uso de un operador, pienso "¿cuál es la función equivalente sobrecargada" de este operador?
Yo sé que los operadores de Java no tienen sobrecarga de operadores, es solo una forma alternativa de hacer una solución.
En este caso:
...
x++;
...
debe leerse como:
...
int /* function */ postincrement (/* ref */ int avalue)
{
int Result = avalue;
// reference value,
avalue = avalue + 1;
return Result;
}
...
postincrement(/* ref */ x);
...
Y:
...
++x;
...
...
int /* function */ preincrement (/* ref */ int avalue)
{
// reference value,
avalue = avalue + 1;
int Result = avalue;
return Result;
}
...
preincrement(/* ref */ x);
...
Entonces, ambas versiones de "++" funcionan como una función que recibe un parámetro variable por referencia.
Entonces, un valor literal como "0 ++" o un resultado de función como "getInt () ++", no son referencias de variable.
Aclamaciones.
Porque como se indica en JLS :
El resultado de la expresión de postfijo debe ser una variable de un tipo que es convertible (§5.1.8) a un tipo numérico, o se produce un error en tiempo de compilación.
Tanto B como C hacen que el compilador diga:
tipo inesperado, requerido: variable, encontrado: valor
Entonces no puedes incrementar un valor, solo una variable.
postincremento y preincremento pueden aplicarse solo con la ayuda de variable.Así que compila el primer caso.
getInt()
no es int
getInt()
devuelve int
++
operador hace dos cosas increment
+ assignment
Entonces, para que funcione el operador ++
necesita una variable para almacenar el resultado de la operación de incremento que no son 0
ni getInt()
.
i++
es una asignación a una variable i
.
En su caso, zero++
es equivalente a zero = zero + 1
. Entonces 0++
significa 0 = 0 + 1
, lo que no tiene sentido, así como getInt() = getInt() + 1
.
Con más precisión :
int oneA = zero++;
medio
int oneA = zero;
zero = zero + 1; // OK, oneA == 0, zero == 1
int oneB = 0++;
medio
int oneB = 0;
0 = 0 + 1; // wrong, can''t assign value to a value.
int oneC = getInt()++;
medio
int oneC = getInt();
getInt() = getInt() + 1; // wrong, can''t assign value to a method return value.
Desde un punto de vista más general, una variable es un valor L , lo que significa que se refiere a una ubicación de memoria y, por lo tanto, puede asignarse. L en L -value significa el lado izquierdo del operador de asignación (es decir =
), incluso si los valores L se pueden encontrar en el lado izquierdo o el lado derecho del operador de asignación ( x = y
por ejemplo).
Lo opuesto es valor R ( R representa el lado derecho del operador de asignación). Los valores R solo se pueden usar en el lado derecho de las instrucciones de asignación, para asignar algo a un valor L. Típicamente, los valores R son literales (números, cadenas de caracteres ...) y métodos.