Почему нельзя использовать тернарный оператор без присваивания (переменная слева)? - PullRequest
0 голосов
/ 23 ноября 2018

Я искал это, и есть некоторые вопросы относительно той же проблемы, но ни один из ответов на эти вопросы, кажется, не отвечает моему запросу.

Я посмотрел спецификацию и смог найти следующееpoints:

  • первое выражение в троичном должно иметь тип boolean

  • второе и третье выражения не могут быть вызовами методов void.

с учетом приведенной выше информации, если я напишу следующий код

String res;
System.out.println(res="walter");

, он выводит Уолтера на консоль, означая, что выражение вернуло что-то, следовательно, оно не является пустым.но теперь, если вы попытаетесь написать это

String stuff = "TV";
String res=null;
stuff.equals ("TV") ? res= "Walter" :  res = "White" ;

, этот код не скомпилируется с Левая часть присваивания должна быть переменной

Даже если оба вышеуказанных условия выполнены (насколько мне известно).почему код не компилируется и почему для него требуется переменная слева?

более того, если я сделаю это

res = stuff.equals("TV")?res="WALTER":res="WHITE";

, код не скомпилируется с

Оператор <= не определен для типа (ов) аргументов java.lang.String, java.lang.String </em>

, но следующая компиляция в порядке

res = stuff.equals("TV")?res="WALTER":"WHITE";

PS

  • Почему в левой части троичного оператора должна быть переменная, возвращаемые значения метода могут быть отброшены, почему это нельзя сделать в случае троичной переменной.
  • Почему Java не позволяет этого, какие проблемы или несоответствия это вызовет, если разрешено

1 Ответ

0 голосов
/ 23 ноября 2018

Условный оператор является выражением: у него есть результат:

int a = cond ? 1 : 2;

, но вы не можете использовать его следующим образом:

cond ? 1 : 2;

, потому что это не StatementExpression;это очень похоже на то, что вы не можете написать ни одного из:

1;
2 * 3;
array[1];

, потому что они просто не служат какой-либо цели.

A StatementExpression - это выражение, которое выможет выдавать ; после, например:

int i = 0;
someMethod(i++);  // Use of i++ as an expression.
i++;              // Use of i++ as a StatementExpression.

Полный список StatementExpression s можно найти в спецификации языка :

StatementExpression:
    Assignment 
    PreIncrementExpression 
    PreDecrementExpression 
    PostIncrementExpression 
    PostDecrementExpression 
    MethodInvocation 
    ClassInstanceCreationExpression

Таким образом, вам не нужно иметь назначение: вы можете использовать условный оператор искусственным образом, например так:

(true ? new int[1] : null)[0]++;

(Не то чтобы я как-то выступал за хороший кодили каким-либо иным способом, просто указав, что это законно)


Что касается остальных ваших проблем: это просто сообщения, специфичные для реализации компилятора.Ваш компилятор использует неверный синтаксис и делает все возможное, чтобы помочь вам, но он не очень хорошо справляется.

Обратите внимание, что другие компиляторы (например, тот, который используется Ideone) выдают совершенно разные сообщения.

Первая форма должна быть написана с использованием if / else:

if (stuff.equals ("TV")) res= "Walter" else res = "White" ;

(кстати, if - это утверждение)

Во второй просто не хватает некоторыхкруглые скобки:

res = stuff.equals("TV")?(res="WALTER"):(res="WHITE");

Хотя назначения во втором и третьем операндах все равно избыточны:

res = stuff.equals("TV")?"WALTER":"WHITE";    
...