Необходимо разбить охранные операторы, чтобы предотвратить дополнительные вычисления? - PullRequest
0 голосов
/ 15 января 2019

Если некоторые защитные заявления важнее других, необходимо ли их разбивать? Например:

guard let someProperty = someProperty,
    someProperty < someValue else {
        return
}

// if some property is OK, unwrap other properties

guard let anotherProperty = anotherProperty,
    let moreProperties = moreProperties else {
        return
}

Приведенный выше пример без вопросов предотвращает ненужное развертывание, если someProperty не соответствует предикату. Однако будет ли выполнен тот же объем работы, если они будут объединены?

guard let someProperty = someProperty,
    someProperty < someValue,
    let anotherProperty = anotherProperty,
    let moreProperties = moreProperties else {
        return
}

Очевидно, что процесс будет проходить сверху вниз, но выполняет ли машина всю защиту и затем оценивает завершение или отказ, или машина выходит из защиты при первом неудачном предложении?

Ответы [ 2 ]

0 голосов
/ 15 января 2019

Защитный оператор работает следующим образом: если первый предикат равен false, он not оценивает следующий предикат (ы).

Другими словами, вы можете считать запятую , оператора охраны такой же, как оператор &&. Это то, что мы называем ленивым оценкой; Если вы проверили, как && работает , вы заметите, что rhs - это автозаполнение возвращает логическое значение, но не - логическое значение, что означает, что оно может даже не оцениваться (в случае lhs параметр равен false).

Хотите узнать больше об автозаполнении? проверьте это из!

Так что для вашего случая вы можете объединить все предикаты (которые, я думаю, будут более читабельными ИМО) в одном guard утверждении.

0 голосов
/ 15 января 2019

Нет нет необходимости разбивать утверждения.

Вы можете легко проверить это, выполнив следующий код:

var condition = false
func failingTest() -> Bool {
  fatalError("this should never execute")
}
guard condition, failingTest() else {
  print("Early exit")
  return
}
  • Когда это печатает Early exit, вы знаете, что он не оценил все условия охранника перед печатью раннего выхода.
  • Когда это вызывает фатальную ошибку, вы знаете, что он выполнил failingTest даже после того, как узнал, что condition было ложным.

При выполнении этого фрагмента кода с использованием Apple Swift version 4.2.1 мы получаем Early exit, поэтому мы знаем, что Swift прекращает оценку условий защиты после первого условия, которое оценивается как false.

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

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