Программирование: стиль IF

Давайте посмотрим на этот образец.

List <String> lst = getSome ();  // returns null or a list
if (lst == null || lst.contains ("bla") == true)
{
   // go on

Это сработает - будет зафиксировано нулевое значение. Но это только так, потому что я знаю, что термин if оценивается слева направо, и он не оценивается полностью, если результат становится неизменным (1 || x всегда 1). По крайней мере, это то, что я увижу, если позволю ему работать.

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

Возникает вопрос: хороший ли стиль в языке позволяет это?

Какой язык вы просите?

François Andrieux 01.11.2018 21:31

Какой у Вас вопрос

chevybow 01.11.2018 21:31

Если вы спрашиваете, всегда ли || закорачивает в Java, да.

ifly6 01.11.2018 21:31
c++ имеет оценку короткого замыкания. stackoverflow.com/questions/628526/…
drescherjm 01.11.2018 21:31

По крайней мере, в C++, в зависимости от короткого замыкания оператора, это обычно не считается слишком непонятным. Разумно ожидать, что другие разработчики будут знать об этой функции и понимать код.

François Andrieux 01.11.2018 21:32

Сегодня я написал подобный код. Лично я считаю, что такое выражение читается довольно хорошо.

George 01.11.2018 21:49

Этот вопрос больше подходит для разработки программного обеспечения. Например, недавно был вопрос Когда оценка короткого замыкания плохая?

chris 01.11.2018 21:49

В Infinity Foundation нет стиля программирования

user4581301 01.11.2018 21:49

Я удалил тег C++, потому что показанный код почти наверняка является Java и потребует очень надуманной реализации List для компиляции на C++.

François Andrieux 01.11.2018 22:02

В Спецификации языка Java (docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-1‌ 5.24) четко указано, что «[он] оценивает свой правый операнд, только если значение его левого операнда ложно». Если бы это когда-либо изменилось, пришлось бы переписать большую часть существующего кода, потому что люди полагаются на такое поведение.

Thomas Kläger 01.11.2018 22:19
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
6
10
87
1

Ответы 1

Давайте посмотрим на этот пример:

private static int personCount = 0;

public static void main(String args[]) {

    boolean firstBool = false;
    if (addPerson(firstBool) || addPerson(true)){
        System.out.println("true");
    }
    System.out.println(personCount);
}

private static boolean addPerson(boolean b){
    personCount++;
    return b;
}

Этот код выводит 2, но если вы измените firstBool на true, он выведет 1.

Есть условное выполнение второй функции, это может заставить других людей упустить тот факт, что эта функция не всегда будет выполняться второй раз. Если эта функция не повлияет ни на что, кроме результата предложения if, тогда все будет в порядке, но в противном случае лучше избегать написания такого кода или, по крайней мере, добавлять к нему комментарий.

Короткое замыкание - это оптимизация, человеку не нужно думать обо всех оптимизациях, происходящих в фоновом режиме, когда он пытается понять, что делает часть кода.

Редактировать:, вы можете избежать короткого замыкания, используя поразрядные операции (& и |) вместо логических операций (&& и ||), таким образом вы можете гарантировать, что обе функции всегда будут выполняться.

Я случайно отправил сообщение до того, как закончил писать, только что отредактировал, чтобы закончить ответ.

potato 01.11.2018 22:00

imho его плохое название, которое затмевает ваш пример, а не ||. Если назвать метод incrementCounter, будет очевидно, что у него есть побочные эффекты.

463035818_is_not_a_number 01.11.2018 22:14

Да, но не для всех очевидно, что эти побочные эффекты иногда не возникают.

potato 01.11.2018 22:14

Я отредактировал пример, теперь у него лучшее название, надеюсь, это лучше демонстрирует мою точку зрения.

potato 01.11.2018 22:18

@drescherjm Нет, если первая функция возвращает истину, то результат оператора || неизбежно будет истинным, поэтому то, что находится на другой стороне оператора ||, не выполняется. Если первая функция выдает false, вам нужно знать результат другой стороны оператора ||, чтобы определить окончательный результат.

potato 01.11.2018 22:29

Приносим извинения за досадную ошибку пользователя. Хотя это показывает вашу точку зрения. Я бы попытался избежать этих побочных эффектов при коротком замыкании.

drescherjm 01.11.2018 22:30

@drescherjm Согласен, добавил в ответ. Также добавлен совет по предотвращению короткого замыкания :)

potato 02.11.2018 15:59

Другие вопросы по теме