Охрана может улучшить четкость
Когда вы используете охранник, у вас гораздо больше ожиданий, что охранник добьется успеха, и несколько важно, что если он не удастся, вы просто захотите выйти из области видимости раньше . Как вы охраняете, существует ли файл / изображение, является ли массив пустым или нет.
func icon() -> UIImage {
guard let image = UIImage(named: "Photo") else {
return UIImage(named: "Default")! //This is your fallback
}
return image //-----------------you're always expecting/hoping this to happen
}
Если вы напишете приведенный выше код с помощью if-let, он покажет читающему разработчику, что это больше 50-50. Но если вы используете guard, вы добавляете ясности в свой код, и это означает, что я ожидаю, что это сработает в 95% случаев ... если это когда-нибудь не удастся, я не знаю, почему это произойдет; это очень маловероятно ... но тогда просто используйте это изображение по умолчанию или, возможно, просто подтвердите с осмысленным сообщением, описывающим, что пошло не так!
Избегайте guard
появления побочных эффектов, охранники должны использоваться как естественный поток. Избегайте осторожности, когда else
статьи вызывают побочные эффекты. Охранники устанавливают необходимые условия для правильного выполнения кода, предлагая ранний выход
Когда вы выполняете значительные вычисления в положительной ветви, выполняйте рефакторинг от if
до guard
оператора и возвращает резервное значение в else
предложении
Из: Книга Эрики Садун "Быстрый стиль"
Кроме того, в результате приведенных выше предложений и чистого кода более вероятно, что вы захотите / должны будете добавлять утверждения в неудавшиеся операторы защиты, это просто улучшает читаемость и дает другим разработчикам понять, чего вы ожидали.
guard let image = UIImage(named: selectedImageName) else { // YESSSSSS
assertionFailure("Missing \(selectedImageName) asset")
return
}
guard let image = UIImage(named: selectedImageName) else { // NOOOOOOO
return
}
Из: Книга Эрики Садун Swift Style + некоторые модификации
(вы не будете использовать утверждения / предварительные условия для if-let
s. Это просто не кажется правильным)
Использование охранников также поможет вам улучшить ясность, избегая пирамиды гибели. См . Ответ Нитина .
Guard создает новую переменную
Есть одно важное различие, которое, как мне кажется, никто не объяснил.
Оба guard let
и if let
развернуть переменную, однако
С помощью guard let
вы создаете новую переменную, которая будет существовать вне else
оператора.
При этом if let
вы не создаете никакой новой переменной - после оператора else вы вводите блок кода, только если необязательный параметр не равен нулю. Вновь созданная переменная существует только внутри блока кода, а не после!
guard let:
func someFunc(blog: String?) {
guard let blogName = blog else {
print("some ErrorMessage")
print(blogName) // will create an error Because blogName isn't defined yet
return
}
print(blogName) // You can access it here ie AFTER the guard statement!!
//And if I decided to do 'another' guard let with the same name ie 'blogName' then I would create an error!
guard let blogName = blog else { // errorLine: Definition Conflicts with previous value.
print(" Some errorMessage")
return
}
print(blogName)
}
if-let:
func someFunc(blog: String?) {
if let blogName1 = blog {
print(blogName1) // You can only access it inside the code block. Outside code block it doesn't exist!
}
if let blogName1 = blog { // No Error at this line! Because blogName only exists inside the code block ie {}
print(blogName1)
}
}
Для получения дополнительной информации if let
см .: Почему повторное объявление необязательной привязки не приводит к ошибке
Охранник требует выхода из прицела
(Также упоминается в ответе Роба Напьера):
Вы ДОЛЖНЫ guard
определить внутри func. Его основная цель - прервать / вернуть / выйти из области действия, если условие не выполняется:
var str : String?
guard let blogName1 = str else {
print("some error")
return // Error: Return invalid outside of a func
}
print (blogName1)
Поскольку if let
вам не нужно иметь его внутри какой-либо функции:
var str : String?
if let blogName1 = str {
print(blogName1) // You don't get any errors!
}
guard
против if
Стоит отметить , что это более уместно , чтобы увидеть этот вопрос , как guard let
против if let
и guard
против if
.
Автономная версия if
не выполняет разворачивания, как и автономная версия guard
. См. Пример ниже. Если есть значение, он не выходит раньше срока nil
. Нет дополнительных значений. Он просто выходит рано, если условие не выполняется.
let array = ["a", "b", "c"]
func subscript(at index: Int) -> String?{
guard index > 0, index < array.count else { return nil} // exit early with bad index
return array[index]
}
if let
когдаnon-nil
случай действителен. Используйте,guard
когдаnil
регистр представляет собой какую-то ошибку.