Особенности языка программирования Swift
Знакомим с особенностями языка Swift. В этой статье мы затронем опционалы, константы, оператор guard, wildcard и другие фишки Свифт.
7К открытий9К показов
Команда мобильной разработки КРОК поделилась полезными особенностями языка Swift, которые призваны облегчить и ускорить процесс разработки.
Опционалы
По сути, это контейнеры, которые либо имеют значение, либо нет — enum с одним из двух значений: nil или любое другое. Эти состояния обозначаются как Nope и Some соответственно. Соответственно, nil — это валидное значение, а не костыль, как в Objective-C, и при создании опциональной переменной присваивается по умолчанию, если значение не указано. Объявляются они так:
А внутри выглядят таким образом (ссылка на исходный код опционала в открытом репозитории свифта: https://github.com/apple/swift/blob/main/stdlib/public/core/Optional.swift):
Благодаря опционалам у языка Swift есть несколько крутых фишек, которых нет в том же Objective-C:
- Все переменные в любой момент в runtime всегда определены и инициализированы. Просто если вы не пишете прямой инициализатор, переменная (если это Optional тип) определяется как nil, а если не Optional, компилятор не позволит вам собрать приложение, ведь вы забыли инициализировать это и это. Так происходит потому, что nil — это особый вид значения, и вы можете сказать компилятору: «это пустая переменная, поэтому проинициализируй её сам».
- Swift почти никогда не выдаёт nullpointerexception. Единственный случай, когда можно нарваться на подобную ошибку — попытаться force unwrap опционал, в котором лежит nil.
Оператор guard
Оператор guard работает примерно так же, как if, но с одним отличием: он запускается, когда условие НЕ выполняется.
Guard-конструкции — это спасение. Они позволяют лаконично описать, что делать, если найдена ошибка — и просто забыть, что эта самая ошибка здесь может быть. Как это выглядит:
Здесь мы пытаемся запросить у API свои данные. В колбеке этого запроса мы проверяем, произошла ли ошибка в процессе: если да, то делаем return, если нет, то передаём полученную data в комплишен дальше.
Wildcard
Когда функция состоит из одного входного параметра, очень долго и лениво писать его название, чтобы передать туда переменную. Поэтому можно поставить нижнее подчёркивание перед параметрами, которые вы хотите опускать при вызове функции. Это называется «Wildcard».
В синтаксисе wildcard будет выглядеть следующим образом: когда вы планируете вызвать функцию, можно не писать имя параметра, а просто поставить значение. Допустим, у нас есть следующая функция:
Если бы в параметрах функции не было вайлдкарда, функцию с переменной myError, внутри которой лежит какая-то конкретная ошибка, пришлось бы вызывать таким образом:
Но благодаря вайлдкарду мы можем написать так:
И позже вызвать функцию:
Ещё к нижнему подчёркиванию можно обратиться, переприсвоить его или передать куда-нибудь.
Константы
Ещё одной особенностью языка Swift является то, что в нём не предусмотрен атрибут константы, и ключевого слова const просто не существует. Вместо этого используется let:
let означает, что мы можем присвоить значение переменной только один раз. И потом либо что-то поменять внутри неё, если это ссылочный тип, либо передать что-то из неё в другое место. А при попытке что-то переприсвоить, компилятор скажет: «так нельзя, я это собирать не буду».
let часто используется для полей класса и параметров. Если переменная нужна в изменяемом виде, — например, это счётчик функции, — то она объявляется через var. Это иногда путает новичков — особенно тех, кто приходит из JavaScript, потому что там между var и let немного другие отношения.
Функции высшего порядка
Функции высшего порядка похожи на лямбда-выражения в Kotlin (но, строго говоря, ими не являются) и что-то делают для каждого элемента коллекции, к которой применяются.
Например, метод map(_:) используется для преобразования последовательностей (тип Sequence). Он очень лаконичный, можно быстро отсортировать коллекцию или посчитать сумму чисел Фибоначчи:
Читабельно ли это? Не очень. У неподготовленного человека или того, кто пишет в соответствии с императивным подходом, это может вызвать сложности.
Другой метод — reduce(_:_:) — уменьшает все элементы до одного значения:
Иногда reduce(_:_:) используется для очень сложных вещей — например посчитать пересечения множеств. Это удобная штука для мелких задач — посчитать сумму массива, найти подмассив, отсортировать что-то.
Атрибуты доступа
В языке программирования Swift «все знают обо всём»: можно из любого файла обратиться к любому классу и любой зависимости, если они открыты. Единственный способ с этим что-то сделать, — например, вы не хотите, чтобы к вашим классам и модулям обращались приложения извне, — это настроить атрибуты доступа. У Swift их шесть:
- public
- private
- protected
- open
- closed
- fileprivate
open и closed — это про наследование. Возможно ли наследоваться от этого класса и можно ли оверрайдить внутри него какие-то поля или методы. Если файл «открытый», от него может наследоваться кто угодно и оверрайдить внутри него что угодно. Если «закрытый», все знают о его существовании и могут делать то, что вы им разрешите. Но наследоваться от него и оверрайдить в нём что-то — нет.
fileprivate — очень интересная штука. Представим, что у вас есть класс, объявленный в Файле 1. В Файле 2 вы пишете для него расширения: добавляете поля, методы и так далее. И один из методов помечаете атрибутом fileprivate. Теперь он будет доступен только в Файле 2. А в других файлах, в том числе в Файле 1, к нему обратиться не получится.
На самом деле, в языке Swift есть и много других особенностей — в данной статье мы постарались перечислить самые основные. Делитесь в комментариях фишками Swift, которые помогают вам в работе.
7К открытий9К показов