логичные операторы swift - PullRequest
       10

логичные операторы swift

0 голосов
/ 10 сентября 2018
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 Как решить этот порядок логических операторов?

Ответы [ 2 ]

0 голосов
/ 10 сентября 2018

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

Итак, в вашем коде 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 , к которой принадлежит логическое ИЛИ ||. И поэтому && имеет больший приоритет, чем ||.

Чтобы узнать больше о группах / уровнях предшествования операторов, посмотрите внизу this или that .

0 голосов
/ 10 сентября 2018

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

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

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

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

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

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

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...