Охорона може підвищити чіткість
Коли ви використовуєте охорону, у вас набагато більша тривалість, щоб охоронець мав успіх, і дещо важливо, що якщо це не вдасться, ви просто хочете вийти зі сфери застосування рано . Як ви охороняєте, щоб побачити, чи існує файл / зображення, чи масив порожній чи ні.
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-нехай він повідомляє розробнику читання, що він більше 50-50. Але якщо ви використовуєте охорону, ви додаєте чіткість своєму коду, і це означає, що я очікую, що це спрацює 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 + деякі модифікації
(ви не будете використовувати твердження / передумови для if-let
с. Це просто не здається правильним)
Використання охоронців також допоможе вам підвищити чіткість, уникаючи піраміди приреченості. Дивіться відповідь Нітіна .
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
випадок представляє якусь помилку.