Быстрые логические операторы упорядочены

func addOne() -> Bool {
    x += 1
    print("111")
    return true
}

if true || addOne() && addOne() && addOne(){
    print("open the door")
} else {
    print("can't open the door")
}

Я знал, что логические операторы вычисляются слева направо, но в этом случае функция addOne не вызывается в этом состоянии.

Итак, значение x - это 0, и я ожидал 2. Как решить этот порядок логических операторов?

Чего вы пытаетесь достичь?

Rob 10.09.2018 10:50

Все, что находится после if true || , игнорируется.

Martin R 10.09.2018 10:51

Также обратите внимание, что && имеет более высокий приоритет, чем ||. Ваше состояние означает true || (addOne() && addOne() && addOne())

Sulthan 10.09.2018 10:55

Мне также интересно, почему вы ожидаете, что x будет 2, если вы (попытаетесь) увеличить его в три раз.

Martin R 10.09.2018 10:58
0
4
593
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Как сказал @Sulthan, оператор && имеет более высокий приоритет, чем ||, поэтому

 true || addOne() && addOne() && addOne()

эквивалентно

true || (addOne() && addOne() && addOne())

Затем обратите внимание, что булевы операторы «замыкают»: если левый операнд || оценивается как true, тогда правый операнд вообще не оценивается. Что ж, true - это правда, поэтому и не называется addOne().

Если вы измените его на

(true || addOne()) && addOne() && addOne()

тогда функция будет вызываться дважды ...

См. Заявления оператора для получения дополнительной информации о приоритете операторов.

Спасибо, я обнаружил, что оператор && имеет более высокий приоритет, чем || в документе Swift

Ijij 11.09.2018 10:19
Ответ принят как подходящий

Он называется Оценка короткого замыкания и означает, что оператор прекращает вычисление сразу после определения результата. Части выражения, содержащие операторы && или ||, оцениваются только до тех пор, пока не станет известно, является ли условие истинным или ложным. Это ускоряет выполнение вычисления выражения.

Итак, в вашем коде true || addOne() && addOne() && addOne() известен как true, как только вы обнаружите true в своем выражении. В целом true || whatever всегда будет верным, поэтому нет необходимости оценивать whatever.

&& имеет приоритет над ||, поэтому:

true || addOne() && addOne() && addOne()

эквивалентно :

true || (addOne() && addOne() && addOne())

И мы уже знаем, что trueИЛИwhatever истинно, поэтому whatever не будет оцениваться.

Чтобы изменить приоритет по умолчанию в вашем выражении, используйте круглые скобки там, где вы сочтете нужным. Например:

(true || addOne()) && (addOne() && addOne())

В этом случае первый addOne() не будет оцениваться, а второй и третий будут оцениваться, поскольку trueА ТАКЖЕsomething - это something. Таким образом, в этом случае x будет равно 2 (если исходно x = 0).

Вот последний пример (я полагаю, вы его уже поняли, если не дайте мне знать в комментариях):

if (true || addOne() && addOne())   &&   addOne()

В этом случае между true и addOne() && addOne() существует ИЛИ. Не оценивая addOne() && addOne(), мы уже знаем, что true || addOne() && addOne() - это true. Таким образом, выражение можно упростить до true && addOne(). Здесь мы должны оценить addOne(), что означает, что x будет равняться 1.


Редактировать

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

Логическое И && принадлежит группе LogicalConjunctionPrecedence, которая имеет более высокий приоритет, чем группа LogicalDisjunctionPrecedence, к которой принадлежит логическое ИЛИ ||. Таким образом, && имеет больший приоритет, чем ||.

Чтобы узнать больше о группах / уровнях приоритета операторов, посмотрите прямо в нижней части это или что.

Спасибо, я обнаружил, что оператор && имеет более высокий приоритет, чем || в документе Swift

Ijij 11.09.2018 10:20

Большое тебе спасибо

Ijij 12.09.2018 04:49

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