guard swift что это такое
Guard Statement Explained in Swift
The guard statement in Swift helps you return your functions early, if a condition isn’t satisfied. In this tutorial we’ll discuss what guard is, and how you can use it in practical iOS development.
Here’s what we’ll get into:
Ready? Let’s get started!
How To Use “guard” in Swift
You use the guard statement in Swift to (early) return a function when a condition isn’t satisfied. It’s similar to an if statement.
Let’s take a look at an example:
In the above code, a hypothetical function sqrt(number:) calculates the square root of a given number and returns it. For example, the square root of 144 is 12, because 12 2 = 144.
Here’s that guard statement once more:
The syntax for guard in Swift is guard condition else < ··· >.
It’s easiest to compare guard to a conditional, i.e. an if statement, that evaluates a logical expression.
It’s easiest to read the above code as: “Guard that number is greater than or equal to zero, or else_, return nil.”_ See how that reads quite naturally?
“Guard that … is true, else, do this.”
If you look closely, you’ll notice that the guard statement is the opposite of an if statement. This doesn’t do guard justice, but it’s important to point out. Here, take a look at this:
The guard statement can only be used to “transfer program control out of scope”. This is a fancy way of saying that the body of the guard block, i.e. what’s inside the squiggly brackets, needs to exit the function (or loop).
You can do so with the following statements:
In the above code we’re using the guard statement to check that an integer i is even, i.e. a multiple of 2. If it’s not, the continue statement causes the loop to continue to the next iteration.
Thanks to that bit of wizardry we can “guard” or “make sure” that a condition is met. And if it’s not, we can respond with exiting the scope.
†: In mathematics, no negative number can have a real square root.
Early Returns – Why?
Is inverting if statements all there is to the guard statement? If it would be, we just might as well use if statements!
Here’s what the official Swift documentation says about guard :
A guard statement is used to transfer program control out of a scope if one or more conditions aren’t met.
When you already know that it doesn’t make sense to continue executing a function, you might as well exit the function early. This principle is called early return (or early escape or exit).
It’s called “early” because you typically exit at the top of the function, when the computationally intense stuff hasn’t happened yet. If you’re not going to like the movie, why watch it all the way to the end?
Early returns are useful for a few reasons:
But… you could say the same about using if for an early return, right? What makes guard superior syntax for early returns?
The guard statement is technically only syntactic sugar, i.e. it merely sugarcoats already existing control flow mechanisms with more expressive syntax. Syntactic sugar is a good thing – if it wouldn’t be, we would all still use punch cards!
Unwrap Optionals with “guard let”
In the above example we’re using guard let to do 3 things:
Let’s disect that statement for a bit. First, imagine your app attempts to authenticate a user with a username and a password. The view controller has a text field property called usernameField of type UITextField? (an optional).
In the above code, we can safely use the username constant, inside the brackets, to authenticate the user. Thanks to if let we are 100% certain that the conditional body is only executed if usernameField?.text has a value.
This code has a few problems, though:
How do you solve this? Here’s how:
What’s counter-intuitive – and super cool – about guard let is that the username constant is available within the scope of the function, and not just the conditional body. You can use username “outside” of the squiggly brackets of the guard let ··· else < ··· >block. Neat!
Using “guard” in Practical iOS Development
If you’re already familiar with software development, you’re hopefully also familiar with the concept of early returns. It’s a good practice to exit a function or scope as soon as possible, if it becomes apparent that continuing execution makes no sense. Go home if movie sucks.
In practical iOS development, you’ll often see the guard statement as a one-liner. Here’s an example:
Author’s Note: I recall a discussion on the Swift message boards about omitting the squiggly brackets, or even making else < return >implicit, but I can’t find it anymore… If doing so is useful, you can surely read about it on Swift Evolution. I wonder if we’ll see implicit guard let age = Int (age) in a future version of Swift.
Moving on. You’re likely to come across something like the following, in your iOS development work:
See what’s happening there? The guard block is used to validate four conditions:
In the above code, we’re even forgoing the guard statement in favor of a more descriptive if statement. It reads more naturally to say: “If username or password is empty”, compared to: “Guard that username not is empty, and password not is empty.” This is up for debate though. If you don’t agree, at least use it as an example to sharpen your thinking.
Further Reading
The guard and guard let statements make your code easier to read, safer, and less error-prone. You can code more productively, knowing that guard statements check a condition and exit if it’s invalid.
If you look closer, you see the tension between designing a programming language that’s convenient for the developer without making it too strict and opinionated. That’s the role of syntactic sugar – making you more productive, and your code more flexible, without getting too much in the way.
In any case, here’s what you learned:
Want to learn more? Check out these resources:
Документация
Инструкции
В Swift существуют три вида инструкций: простые инструкции, инструкции управления компилятором, а также инструкции управления потоком. Простые инструкции являются наиболее распространенными и состоят либо из выражения или объявления. Инструкции управления компилятором позволяют программе изменять аспекты поведения компилятора, включают в себя конфигурацию сборки и инструкции управления строкой.
Инструкции управления потоком используются для управления потоком выполнения программы. Есть несколько типов инструкций управления потоками в Swift, в том числе инструкции цикла, инструкции ветвления, а также инструкции передачи управления. Инструкции цикла позволяют блоку кода выполняться несколько раз, инструкции ветвления позволяют определенному блоку кода выполняться только при выполнении определенных условий, а также инструкции передачи управления обеспечивают возможность изменять порядок, в котором будет выполняться код. Кроме того, Swift предоставляет инструкцию do для представления области для обработки ошибок, а также инструкцию defer для запуска очистки непосредственно перед как мы покинем эту область видимости.
Точка с запятой ( ; ) может использоваться по желанию после любой инструкции и используется для разделения нескольких инструкций, если они находятся в одной и той же строке.
Грамматика инструкций
Инструкции цикла
Управление потоком в инструкции цикла может быть изменено инструкцией break и continue и более подробно обсуждается в «Инструкция Break» и «Инструкция Continue» ниже.
Грамматика инструкции цикла
Инструкция for-in
Выглядит следующим образом:
Грамматика инструкции for-in
Инструкция while
Инструкция while позволяет блоку кода выполняться несколько раз, до тех пор, пока условие остается верным.
Инструкция while выглядит следующим образом:
Инструкция while выполняется следующим образом:
Поскольку значение условия вычисляется до выполнения самих инструкций, инструкции в инструкции while могут выполняться ноль или более раз.
Грамматика инструкции while
Инструкция repeat-while
Инструкция repeat-while позволяет блоку кода выполняться один или несколько раз, до тех пор, пока условие остается верным.
Выглядит следующим образом:
Грамматика repeat-while инструкции
Инструкции ветвления
Управление потоком в инструкции if или инструкции switch может быть изменено инструкцией break и рассматривается в разделе Инструкция break ниже.
Грамматика инструкций ветвления
Инструкция if
Инструкция if используется для выполнения кода, на основе оценки одного или нескольких условий.
Грамматика инструкции if
Инструкция guard
Инструкция guard используется для перевода контроля программы из области видимости, если одно или несколько условий не выполняются.
Выглядит следующим образом:
Значение любого состояния в инструкции guard должно иметь тип, соответствующий протоколу Boolean. Условие может быть также объявлением опциональной привязки, см. Привязка опционалов.
Грамматика инструкции guard
Инструкция switch
Инструкция switch позволяет определенным блокам кода выполняться в зависимости от значения контрольного выражения.
Инструкция switch имеет следующий вид:
Инструкция Switch должна быть исчерпывающей
В Swift каждое возможное значение типа контрольного выражения должно соответствовать значению, по меньшей мере, одного шаблона кейса. Когда это просто не представляется возможным (например, когда тип контрольного выражения является Int ), вы можете включить дефолтный кейс ( default ), чтобы удовлетворить требование.
Переключение между будущими кейсами перечисления
Выполнение неявно не “проваливается” через кейсы
Грамматика инструкции switch
Маркированная инструкция
О том как использовать маркеры инструкции см. Маркированные инструкции.
Грамматика маркированных инструкций
Операторы передачи управления
Грамматика инструкции передачи управления
Инструкция break
Грамматика инструкции Break
Инструкция continue
Когда за оператором continue следует имя маркера инструкции, оно заканчивает выполнение программы текущей итерации инструкции цикла, названного этим маркером.
Когда за оператором continue не следует имя маркера инструкции, оно заканчивает выполнение программы текущей итерации самого внутреннего инструкции цикла, в котором находится.
В обоих случаях, управление программой затем переносится на состояние внутренней инструкции цикла.
Грамматика инструкции Continue
Инструкция fallthrough
Грамматика инструкции fallthrough
Инструкция return
Инструкция return встречается в теле функции или определения метода и благодаря ему выполнение программы возвращается к вызову функции или метода. Выполнение программы продолжается сразу после вызова функции или метода.
Когда за инструкцией return следует выражение, значение выражения возвращают к вызову функции или метода. Если значение выражения не совпадает со значением возвращаемого типа, объявленного в функции или в объявлении метода, то значение выражения преобразуется в тип возвращаемого значения, прежде чем он будет возвращен к вызывающей функции или методу.
Заметка
Как описано в разделе Проваливающиеся инициализаторы, специальная форма инструкции return ( return nil ) может быть использована в failable инициализаторе для того, чтобы информировать о неудачной инициализации.
Когда за инструкцией return не следует выражения, оно может быть использовано только для возврата из функции или метода, не возвращающих значение (то есть, когда тип возвращаемого значения функции или метода Void или () ).
Грамматика инструкции return
Инструкция throw
Грамматика инструкции throw
Инструкция defer
Инструкция defer имеет следующий вид:
Инструкции внутри инструкции defer выполняются независимо от того, каким образом передается управление программой. Это означает, что инструкцию defer можно использовать, например, для выполнения ручного управления ресурсами, такими как закрытие дескрипторов файлов, а также для выполнения действий, которые должны произойти, даже если возникнет ошибка.
Грамматика инструкции defer
Инструкция do
Инструкция do в Swift похожа на фигурные скобки ( <> ) в C и используется для разделения блока кода, и не снижает производительность во время выполнения.
Инструкция do выглядит так:
Как и инструкция switch, компилятор пытается сделать вывод о том, являются ли условия catch исчерпывающими. Если такое определение может быть сделано, то ошибка считается обработанной. В противном случае ошибка может распространиться из содержащей ее области, а это значит, что ошибка должна быть обработана с помощью включенного условия catch или содержащаяся функция должна быть объявлена с throws.
Для того, чтобы убедиться, что ошибка обрабатывается, используйте условие catch с шаблоном, который подходит ко всем ошибкам, например шаблон (_). Если условие catch не указывает шаблон, то условие catch подходит и связывает любую ошибку локальной константы с именем error. Для получения дополнительной информации о шаблонах см. Шаблоны.
Подробнее об использовании инструкции do с условиями catch, см. Обработка ошибок.
Грамматика инструкции do
Инструкции управления компиляторами
Инструкции управления компиляторами позволяют программе изменять аспекты поведения компилятора. В Swift есть две инструкции управления компиляторами: инструкция сборки конфигурации и инструкция управления строкой.
Грамматика инструкций управления компилятором
Блок условной компиляции
Блок условной компиляции позволяет коду быть условно скомпилированным в зависимости от значения одного или нескольких конфигураций сборки.
Условие платформы | Действительные аргументы |
---|---|
os() | macOS, iOS, watchOS, tvOS, Linux |
arch() | i386, x86_64, arm, arm64 |
swift() | >= с последующим указанием номером версии |
canImport() | Имя модуля |
targetEnvironment() | simulator |
Заметка
Заметка
Каждая инструкция в теле блока условной компиляции анализируется, даже если он не компилируется. Тем не менее, есть исключение, когда блок условной компиляции включает в себя функцию тестирования версии языка. Инструкции анализируются, только если версия компилятора Swift соответствует той, что указана в функции тестирования версии языка. Это делается для гарантии того, что устаревший компилятор не будет разбирать синтаксис более поздних версий Swift.
Грамматика блока условной компиляции
Инструкция управления строкой
Инструкция управления строкой используется для указания номера строки и имени файла, которые могут отличаться от номера строки и имени файла исходного компилированного кода. Используйте инструкцию управления строкой для изменения локализации исходного кода, используемого в Swift для целей диагностики и отладки.
Инструкция управления строкой имеет следующий вид:
Инструкция управления строкой изменяет значения #line и #file выражения литералов, начиная со строки кода после инструкции управления строкой. Номер строки изменяет значение #line и может быть любым целым числом больше нуля. Имя файла изменяет значение #file и является строковым литералом.
Грамматика инструкции управления строкой
Диагностический оператор времени компиляции
Оператор диагностики времени компиляции заставляет компилятор выделять ошибку или предупреждать во время компиляции. Диагностическая инструкция для компиляции имеет следующие виды:
Первый пример показывает сообщение об ошибке как фатальную ошибку и завершает процесс компиляции. Второй вариант выдает предупреждающее сообщение как нефатальное предупреждение и позволяет компиляции продолжить. Вы пишете диагностическое сообщение как статический строковый литерал. Статические строковые литералы не могут использовать такие функции, как строковая интерполяция или конкатенация, но они могут использовать синтаксис многострочного строкового литерала.
Грамматика оператора диагностики времени компиляции
Условие доступности
Условие доступности выглядит так:
Вы можете использовать условие доступности для выполнения блока кода, в зависимости от того, доступны ли во время выполнения API-интерфейсы, которые вы хотите использовать. Компилятор использует информацию из состояния готовности, когда он проверяет, что API-интерфейсы в этом блоке кода доступны.
Грамматика условий доступности
Если вы нашли ошибку, пожалуйста, выделите фрагмент текста и нажмите Ctrl+Enter.
Свифт гвардии сайта
Swift 2 представил guard ключевое слово, которое может использоваться для обеспечения готовности различных данных. Пример, который я видел на этот сайт демонстрирует функцию submitTapped:
мне интересно, если с помощью guard отличается от того, чтобы делать это старомодным способом, используя if состояние. Дает ли это преимущества, которые вы не могли бы получить, используя простой чек?
12 ответов
чтение в этой статье я заметил большие преимущества, используя гвардии
здесь вы можете сравнить использование guard с примером:
это часть без охраны:
здесь вы помещаете желаемый код во все условия
вы можете не сразу увидеть проблему с этим, но вы можете себе представить, насколько запутанной она может стать, если она была вложена с многочисленными условиями что все должно быть выполнено, прежде чем запускать ваши заявления
способ очистить это-сначала выполнить каждую из ваших проверок и выйти, если они не выполнены. Это позволяет легко понять, какие условия заставят эту функцию выйти.
но теперь мы можем использовать guard, и мы видим, что можно решить некоторые проблемы:
эта же закономерность сохраняется true для необязательных значений:
если у вас остались какие-либо вопросы вы можете прочитать всю статью: заявление Swift guard.
Подводя Итоги
и, наконец, чтение и тестирование я обнаружил, что если вы используете guard, чтобы развернуть любые optionals,
эти развернутые значения остаются вокруг для вас, чтобы использовать в остальной части вашего блок кода
здесь развернутое значение будет доступно только внутри блока if
другое преимущество часто логика, которую вы хотите реализовать, больше» if not let » чем » if let < >else «.
вот пример: Предположим, вы хотите реализовать accumulate – между map и reduce где он возвращает вам массив под управлением уменьшает. Вот он с guard :
как бы ты написал без гвардии, но все еще используя first что возвращает необязательный? Что-то вроде этого:—14—>
дополнительная вложенность раздражает, но также не так логично иметь if и else так далеко друг от друга. Гораздо более читабельно иметь ранний выход для пустого случая, а затем продолжить с остальной частью функции, как если бы это не было возможность.
при выполнении условия с помощью guard Он предоставляет переменные, объявленные в guard блок для остальной части кода-блока, приведя их в свою область. Который, как уже говорилось ранее, обязательно пригодится с вложенными if let заявления.
обратите внимание, что guard требует возвращение или бросить в своем заявлении else.
разбор JSON с Guard
Ниже приведен пример того, как можно проанализировать объект JSON, используя охранять, а не если-пускай. Это выдержка из записи в блоге, которая включает в себя файл playground, который вы можете найти здесь:
Подробнее:
если условие заявления предохранителя выполнено, выполнение кода продолжается после заявления охранника закрывается скоба. Любые переменные или константы которые были присвоены значения, используя необязательную привязку как часть условие доступно для остальной части блока кода, который охранник появляется заявление.
если это условие не выполняется, код внутри else выполняется выполненный. Эта ветвь должна передать управление для выхода из блока кода что это заявление охранника появляется. Это можно сделать с контроля передача оператор, такой как return, break или continue, или может вызывать функция или метод, который не возвращается, например fatalError().
одним из преимуществ является устранение вложенные if let заявления. См. видео WWDC «What’s New in Swift» около 15: 30, раздел под названием «Пирамида судьбы».
С помощью гвардии наше намерение ясно. мы не хотим выполнять остальную часть кода, если это конкретное условие не выполняется. здесь мы можем расширить цепь тоже, пожалуйста, посмотрите на ниже кода:
когда использовать guards
если у вас есть контроллер вида с несколькими элементами UITextField или другим типом пользовательского ввода, вы сразу заметите, что вы должны развернуть текстовое поле.текст необязательно, чтобы добраться до текста внутри (если есть!). isEmpty не принесет вам никакой пользы здесь, без ввода текстовое поле просто вернет ноль.
таким образом, у вас есть несколько из них, которые вы разворачиваете и в конечном итоге передаете функции, которая отправляет их на конечную точку сервера. Мы не хотим код сервера должен иметь дело с нулевыми значениями или ошибочно отправлять недопустимые значения на сервер, поэтому мы сначала развернем эти входные значения с помощью guard.
без охранника
без использования guard, мы бы в конечном итоге с большой кучей кода, который напоминает пирамида судьбы. Это не очень хорошо масштабируется для добавления новых полей в нашу форму или для очень читаемого кода. Отступ может быть трудно следовать, особенно с таким количеством других утверждений на каждой развилке.
Да, мы могли бы даже объединить все это, если бы операторы let в один оператор, разделенный запятыми, но мы потеряли бы возможность выяснить, какой оператор не удался и представить сообщение пользователю.
1) это позволяет мне уменьшить вложенный оператор if
2) это увеличивает мою область, которая доступна моей переменной
если заявление
заявление охранника
Заявление Охранника
оператор guard используется для передачи управления программой из области, если одно или несколько условий не выполнены.
Synatx:
преимущество:
1. Используя guard оператор мы можем избавиться от глубоко вложенных условных обозначений, единственная цель-проверка набора требований.
2. Он был разработан специально для раннего выхода из метода или функции.
если вы используете, если ниже приведен код, как он выглядит.
использование guard вы можете передать управление из области, если одно или несколько условий не выполнены.
ссылки:
посмотрите, если это прилипает.
как оператор if, guard выполняет операторы на основе логического значения выражения. В отличие от оператора if, операторы guard выполняются только в том случае, если условия не выполнены. Вы можете думать о guard больше как Assert, но вместо того, чтобы врезаться, вы можете изящно выйти.
проще говоря, он предоставляет способ проверки полей перед выполнением. Это хороший стиль программирования, поскольку он повышает читаемость. В других языках это может выглядеть так:
но поскольку Swift предоставляет вам optionals, мы не можем проверить, если это nil и присвоить значение переменной. В отличие от этого, if let проверяет, что это не nil и присваивает переменную для хранения фактического значения. Вот где guard вступает в игру. Это дает вы более лаконичный способ выхода из раннего использование опциями.