Как научиться программировать на swift: полное руководство

Классы и структуры в функциональной парадигме

Изначально, я думал, что ФП — это только про функции, а классы и структуры используются только в ООП. Но оказалось, классы тоже вписываются в концепцию ФП. Только и они должны быть, скажем так, «чистыми».

«Чистый» класс — класс, все методы которого являются чистыми функциями, а свойства неизменяемы. (Это неофициальный термин, придуман во время подготовки к докладу).

Взглянем на такой класс:

Его можно рассматривать как инкапсуляцию данных…

и функций по работе с ними.

С точки зрения ФП, использование класса User ничем не отличается от работы с примитивами и функциями.

Объявим значение — пользователя Ваню.

Применим к нему функцию getFullname.

В результате получим новое значение — полное имя пользователя. Так как изменить параметры свойства ivan нельзя, результат вызова getFullname неизменен.

Конечно внимательный читатель может сказать: «Постой-ка, метод getFullname возвращает результат на основе глобальных для него значений — свойств класса, а не аргументов». Но на самом деле метод — это просто функция, в которую в качестве аргумента передается объект.

Swift даже поддерживает эту запись в явном виде:

Подсоединяем Actions(действия) к вашему View Controller’у

Точно также как вы соединили элементы со свойствами вашего view controller’а, вам нужно так же соединить определенные действия ваших элементов (например, нажатие кнопки) с методами вашего view controller’а.

Откроем ViewController.swift и добавим эти три метода в ваш класс:

Когда вы объявляете функции обратного вызова для действий с элементом они всегда должны иметь ту же подпись — функция без возвращаемого значения, которая принимает один параметр типа AnyObject, как параметр, который представляет класс любого типа.

Заметка

AnyObject — эквивалент для id в Objective-C.

Для того чтобы Interface Builder заметил ваши новые методы, вам нужно использовать ключевое слово @IBAction (точно так же как и в случае с @IBOutlet).

Далее, откройте Main.stroryboard и убедитесь что в схеме документа вы выделили свой view controller. Также убедитесь, что ваш Connections Inspector (6 вкладка) открыт и вы увидите новые методы в секции Recieved Actions.

Найдите кружок справа от calculateTapped и перетащите его на кнопку Calculate. В появившемся окне выберите Touch Up Inside:

Другими словами мы говорим :»Вызывать мой метод calculateTapped: тогда, когда пользователь уже убирает палец с экрана».

Теперь повторим то же самое для остальных двух методов:

  • Перетащим taxPercentageChanged на ваш слайдер и соединим его с действием Value Changed, которое вызывается каждый раз, как только пользователь двигает слайдер.
  • Перетащим viewTapped на Tap Gesture Recognizer в схему документа. Никаких действий для этого нет, так что ваш метод будет просто вызываться, когда распознает соответствующее движение.

Заметка

Точно так же как и в случае со свойствами, так и для методов, есть сокращенный вариант соединения с действиями, используя Interface Builder.

Вы можете просто ctrl-перетащить от, скажем, кнопки в ваш Swift код вашего View Controller’а в Assistant Editor. В появившемся окне вам нужно выбрать Action и дать имя вашего метода.

Таким образом вы создадите метод в вашем Swift файле и соедините его с действием всего за один шаг. И снова, используйте тот метод соединения, который вам больше всего нравится.

Добавление и удаление

Для того, чтобы вставить символ в строку по указанному индексу, используйте insert(_:at:) метод, а для того, чтобы вставить содержимое другой строки по указанному индексу, используйте метод insert(contentsOf:at:).

Для того, чтобы удалить символ из строки по указанному индексу используйте remove(at:), если вы хотите удалить значения по указанному диапазону индексов, используйте метод removeSubrange(_:):

Заметка

Вы можете использовать методы insert(_:at:), insert(contentsOf:at:), remove(at:) и removeSubrange(_:) с любыми типами, которые соответствуют протоколу RangeReplaceableCollection. Это включает в себя String, как показано тут, а так же коллекции, такие как Array, Dictionary и Set.

Подстроки

Вы можете получить подстроку из строки, например, используя сабскрипт или метод типа и prefix(_:), результат которого возвращает экземпляр подстроки, а не другую строку. Подстроки в Swift имеют практически те же самые методы, что и строки, что означает, что вы можете работать с подстроками так же как и со строками. Однако, в отличие от строк, вы используете подстроки непродолжительное время, пока проводите какие-то манипуляции над строками. Когда вы готовы хранить результат более продолжительное время, то вы конвертируете подстроку в строку. Например:

Как и строки, каждая подстрока имеет область в памяти, где хранятся символы, создающие эту подстроку. Разница между строками и подстроками в том, что для оптимизации производительности подстрока может использовать часть памяти, используемую для хранения исходной строки или часть памяти, которая используется для хранения другой подстроки. (Строки так же имеют похожую оптимизацию, но если две строки делят между собой память, то они считаются равными.) Это оптимизация означает, что у вас не будет потери производительности через копирование памяти, если вы не изменяете строку или подстроку. Как уже было сказано ранее, подстроки не подходят для долгосрочного хранения, так как они повторно используют хранилище исходной строки. Исходная строка должна находиться в памяти до тех пор, пока одна из ее подстрок все еще используется.

В примере выше и greeting является строкой, которая имеет свою область памяти, где создающие ее символы хранятся. Так как и beginning, является подстрокой от greeting, то она переиспользует память. которую использует greeting. И наоборот, newString является строкой, которая была создана из подстроки и теперь она имеет свое хранилище. Рисунок ниже поможет нам разобраться с этими взаимоотношениями:

Заметка

И String, и Substring реализуют протокол StringProtocol, что означает, что очень часто бывает удобно для строковых манипуляций принимать значение StringProtocol. Вы можете вызывать такие функции со значением String или Substring.

Swift предусматривает три способа сравнения текстовых значений: равенство строк и символов, равенство префиксов, и равенство суффиксов.

Собираем нейронку на Swift с помощью фреймворка Metal Shaders

Зачем читать: если вы интересуетесь нейросетями или вам интересен фреймворк Metal Performance Shaders.

Где читать: на Medium.

Евгений Стефанков — разработчик под iOS и лауреат Swift Student Challenge 2020 и 2021. Он уже давно интересуется нейронками — даже написал статью о том, как собрать нейросеть на Swift с нуля. В своей новой статье он показывает, как сделать ту же нейросеть быстрее с помощью фреймворка Metal Performance Shaders.

Это полноценный пошаговый гайд — весь процесс создания умной сетки разобран детально и скрупулёзно: от необучаемых слоёв до обучения и оценки. В конце Евгений скормил нейронке знаки хираганы — японской слоговой азбуки. Через 10 минут программа уже вовсю классифицировала японские символы — с точностью 75%. С цифрами она справилась ещё лучше — за те же 10 минут точность выросла до 98%.

Соединение вашего View Controller’а с вашей моделью

Уже почти все закончили. Все что осталось сделать, так это соединить ваш View Controller с вашей моделью.

Откройте ViewController.swift и добавьте свойство для модели вашего класса и метод для обновления пользовательского интерфейса:

Давайте пройдемся в refreshUI по одной строчке:

  1. В Swift вам нужно явно конвертировать один тип в другой. Здесь мы конвертируем tipCalc.total из Double в String
  2. Вы хотите, чтобы процент налога отображался как целое число (то есть от 0%-10%), чем дробное (что-то вроде 0.06). Так что просто умножим на 100.
  3. Помните, что это действие необходимо, так как свойство taxPctSlider.value является типом Float.
  4. Тут мы используем интерполяцию для обновления ярылка, отображающего процент налога.
  5. Очищаем результат в текстовом поле (text view) до тех пор пока пользователь не нажал кнопку Calculate.

Следующее, добавим вызов refreshUI внизу в viewDidLoad:

Так же имплементируем taxPercentageChanged и viewTapped:

taxPercentageChanged просто обращает «умножение на 100», в то время как viewTapped вызывает resignFirstResponder в поле totalTextField, когда пользователь нажал на view(что и заставляет клавиатуру исчезнуть с экрана).

Остался один метод. Имплементируем calculateTapped:

Давайте все разберем по порядку:

Заметка

Вот как это все работает, если вам это интересно.

Во время написания этого туториала класс String в Swift не имеет доступа ко всем методам, в отличии от NSString (NSString — класс в фреймворке Foundation). Если быть конкретным, то класс String в Swift не имеет метода, который бы преобразовывал тип String в тип Double, хотя NSSting такой метод имеет.

Вы можете вызвать (XXX as NSString)() в Swift для преобразования String в NSString. После чего вы можете использовать любой метод, доступный для NSString, например, метод, преобразующий String в Double.

  1. Тут нужно преобразовать тип String в Double. Это несколько коряво так делать, но думаем, уже скоро будет способ поприличнее.
  2. Здесь вы вызываете метод returnPossibleTips модели tipCalc, которая возвращает словарь с возможными процентами чаевых.
  3. Это то, как вы перебираете словарь через ключи и значения одновременно. Удобно, не так ли?
  4. Здесь мы используем интерполяцию строк, для создания строки, которую поместим в текстовое поле. Мы используем \n для начала новой строки.
  5. Наконец, мы присваиваем текстовому полю значение result.

Вот и все! Запускайте и наслаждайтесь вашим калькулятором чаевых!

Это конечный вариант нашего Xcode проекта.

Урок подготовил: Иван Акулов
Источник урока: http://www.raywenderlich.com/74904/swift-tutorial-part-2-simple-ios-app

Создание элементов интерфейса приложения

Помните, что ваш класс TipCalculatorModel имеет два значения для ввода: общая сумма (total) и процент налога (tax percentage).

Было бы здорово, если бы пользователь смог вводить значения с цифровой клавиатуры, таким образом, текстовое поле (Text Field) подходит идеально для этих целей. Что же касается ввода процента налога, то обычно запрещено использовать его для маленьких значений, так что лучше мы будем использовать слайдер (Slider).

В дополнение к текстовому вводу и слайдеру, нам также нужно: установить ярлыки (Label), панель навигации для отображения названия приложения, кнопку для выполнения вычислений и еще одно текстовое поле для вывода результата.

Давайте детально рассмотрим пользовательский интерфейс.

  1. Navigation Panel (или панель навигации). Вместо того, чтобы добавить панель навигации напрямую, выберите ваш View Controller, выделив его в иерархии документов как на рисунке: После этого идите в Editor\Embed In\Navigation Controller. Это установит вам панель навигации в ваш View Controller (отныне экран будем называть именно так). Сделайте двойной щелчок на панели навигации (Navigation Bar, которая внутри вашего View Controller) и установите имя Tip Calculator.

  2. Labels (или ярлыки). Перетащите Label или по-русски «ярлык» в ваш View Controller. Сделайте двойной щелчок мыши по ярлыку Label и напишите Bill Total (Post-Tax):. Выберите Label и нажмите на пятую вкладку в Inspector, установите там X=33 и Y=81. Повторите все то же самое и для второго ярлыка, только назовите его Tax Percentage (0%): X=20 и Y=120.

  3. Text Field (текстовое поле). Из библиотеки элементов перетащите объект под названием Text Field в ваш View Controller. В инспекторе атрибутов (atribute inspector) установите Keyboard Type = Decimal Pad. В инспекторе размеров (Size Inspector) установите: X=192, Y=77 и Width=392. 
  4. Slider (или слайдер). Перетащите Slider из библиотеки в ваш View Controller. В Attribute Inspector установите Minimum Value=0 (минимальное значение), Maximum Value=10 (максимальное значение) и Current Value=6 (текущее значение). В Size Inspector установите X=190, Y=116 и Width=396.
  5. Button (или кнопка). Из Object Library (привыкаем к английскому) перетаскиваем Button (или кнопку) в ваш View Controller. Сделайте двойной щелчок на кнопке и переименуйте в Calculate. В Size Inspector установите X=268, Y=154.
  6. Text View. Из Object Library перетаскиваем Text View в ваш View Controller. Сделайте двойной щелчек на Text View и удалите текст плейсхолдера. В Attribute Inspector убедитесь в том, что Editable и Selectable не выбраны! В Size Inspector установите X=16, Y=192, Width=568, Height=400.
  7. Tap Gesture Recognizer (элемента, распознающий движения). Из Object Library перетаскиваем Tap Gesture Recognizer в ваш Main View (используйте иерархию элементов для того, чтобы точно выделить Main View, а не элемент внутри него). Эта штука будет работать тогда, когда пользователь будет нажимать на элемент view для того, чтобы клавиатура исчезла.
  8. Auto Layout или (автопозиционирование). Interface Builder часто делает всю грязную работу за нас, когда устанавливает ограничения расположения элементов самостоятельно. В нашем случае мы как раз это и можем использовать. Для того, чтобы это сделать, выберите Main View в иерархии документа и нажмите третью кнопку в правой нижней части Interface Builder’а. Выберете Add Missing Constraints (или добавить недостающие ограничения расположения элементов).

Теперь запустите свой симулятор iPhone 6 и вы должны увидеть, что базовый интерфейс пользователя уже работает!

Базовые типы и управление потоком в Swift

Только что вы познакомились с типом Int, который является типом для обозначения целочисленных значений, но есть еще несколько других типов.

Float и Double

Давайте попробуем вставить еще пару строк в конец нашей игровой площадки и познакомимся с базовыми типами Float и Double:

Есть два типа для работы с числами с плавающей точкой: Float и Double:

  • Double — представляет собой 64-битное число с плавающей точкой. Используйте его когда число с плавающей точкой должно быть очень большим или чрезвычайно точным
  • Float — представляет собой 32-битное число с плавающей точкой. Используйте его, когда значение не нуждается в 64-битной точности.

Тип Double — более точный, чем Float и является типом по умолчанию. Это значит, что константа priceInferred, является так же типом Double. Поэтому, если мы хотим заменить тип Double на тип Float, мы должны написать следующее:

Bool

Вписываем себе пример констант логического типа Bool:

Обратите внимание, что логические значения в Swift имеют значения true или false, в отличии от YES/NO в Objective-C. Так же как с Int и Double, вам не нужно указывать константы или переменные как Bool, если при создании вы присвоили им значения true или false

Подобрались к строковым значениям:

Обратите внимание, что больше мы не используем символ @ как в Objective-C

Конструкции If и интерполяция строк

Условное выражение выглядит очень похоже на любой другой язык. Круглые скобки вокруг условия опциональны, а вот фигурные скобки обязательны даже в тех случаях, когда вам нужно исполнить всего одну строку кода!

Так, в примере выше есть новая техника, называемая интерполяция строк. Если вы захотите вставить что-то в строку, что может быть заменено по значению, то вы должны использовать вот такой простой синтаксис: «\(ваше выражение)».

Вы можете наблюдать работу функции print() в боковой панели, но это может быть проблематично, если ваша строка длинная. Для того, чтобы увидеть результат полностью вам нужно нажать на пиктограмму глаза, в правой части playground’а, который появится при наведении на строку результата:

Есть и другой способ посмотреть длинное значение выражения. Вам нужно пройти в главное меню Xcode (то, что наверху) View\Assistant Editor\Show Assistant Editor.

Assistant Editor покажет вам результат работы функции print() без наведения на строку результата, что согласитесь, само по себе проще. Если вы что-то не поняли, то можете скачать наш файл playground’а со всем кодом что был написан выше.

Массивы и цикл For

В данный момент у нас есть некоторое дублирование кода, потому что мы вызываем метод calcTipWithTipPct несколько раз, с различным процентом чаевых. Вы можете уменьшить дублирование кода, используя массив.

Замените содержимое printPossibleTips вот это:

Мы создали массивы с явным указанием типа и без него (просто для демонстрации). Не забывайте, что синтаксис является сокращенным вариантом Array<Double>.

Теперь, добавим эти строки ниже:

Вы можете написать альтернативный вариант вот в такой форме:

Оператор ..< является полузакрытым оператором диапазона и не включает в себя верхнюю границу. Есть также оператор … который является закрытым.

Массивы имеют свойство count, для подсчета количества своих элементов. Вы так же можете обратиться к конкретному элементу, используя синтаксис arrayName, который мы использовали здесь.

1. Песочница

В 2014 году Apple представила «песочницу» как часть Xcode 6. Песочница является отличным инструментом для изучения языка программирования Swift. С песочницей вы можете сфокусироваться непосредственно на коде, который вы пишете, вместо того, чтобы возиться с настройками проекта, файлами и папками.

Давайте же создадим песочницу, чтобы начать изучать основы Swift. Запустите Xcode 7.1 и выберите New > Playground… из пункта File в главном меню Xcode. Песочницы можно создавать под следующие платформы: OS X, iOS и tvOS. Выберите в пункте Platform значение iOS и назовите песочницу Swift in a Nutshell.

Укажите в Xcode расположение, куда вы хотите сохранить песочницу, и нажмите Create. На первый взгляд, песочница выглядит как простой файл с расширением .playground, но на самом деле это папка с кучкой файлов. К счастью, это совершенно не имеет для нас значения. С песочницей намного проще работать, чем с обычными проектами Xcode с массой файлов и папок.

Пользовательский интерфейс песочницы абсолютно чистый и простой. Слева находится редактор кода, а вывод — справа. Xcode уже наполнил песочницу тремя строчками кода. Первая строка должна выглядеть знакомо, если вы прочитали предыдущий урок.

Строка, начинающаяся с двух прямых слэшей, , показывает, что эта строка — комментарий, который компилятор проигнорирует. Комментарии, занимающие несколько строк, начинаются с и заканчиваются .

Xcode также добавил инструкцию для импортирования фреймворка UIKit. UIKit — самый важный фреймворк для iOS разработки. Он определяет строительные блоки, из которых строится любое iOS приложение. В Swift импортировать фреймворк можно, просто написав ключевое слово , за которым следует имя фреймворка, то есть UIKit в данном случае.

Последняя строка может некоторым из вас напомнить о JavaScript. Используем ключевое слово , чтобы объявить переменную , и присвоим ей значение . Этот пример демонстрирует одну из ключевых особенностей языка Swift — выведение типов.

Но пример, приведенный выше, может ввести в заблуждение. Можно подумать, что Swift является слабо-типизированным языком, но на самом деле это совсем не так. Переменная имеет тип . Swift достаточно умён, чтобы вывести тип переменной , посмотрев на значение, которое мы собираемся ей присвоить.

Следующий пример является эквивалентным. Здесь мы явно указываем тип переменной . Двоеточие, следующее за именем переменной, можно прочитать как имеет тип.

Функциональные атрибуты в Swift

Я уже писал о том, что многие инструменты, реализации и подходы, считающиеся частью той или иной парадигмы, на самом деле могут применяться и в других парадигмах. Например, частью ФП считаются монады, алгебраические типы данных, автоматический вывод типов, строгая типизация, зависимые типы, проверка корректности программы во время компиляции. Но многие из этих инструментов мы можем найти и в Swift.

Строгая типизация и вывод типов — часть Swift. Их не нужно понимать или вводить в проект, они просто у нас есть.

Алгебраические типы данных имеются, и это крутая, но сложная для понимания математическая штука. Прелесть в том, что ее не надо понимать математически, чтобы использовать. Например Int, enum, Optional, Hashable — это алгебраические типы. И если Int есть во многих языках, а Protocol есть и в Objective-C, то enum со связанными значениями, протоколы с дефолтной реализацией и ассоциативными типами есть далеко не везде.

Проверку корректности во время компиляции часто упоминают, говоря о таких языках, как rust или haskell. Подразумевается, что язык настолько выразителен, что позволяет описать все краевые случаи так, чтобы их проверил компилятор. А значит, если программа скомпилировалась, то она обязательно будет работать. Никто не спорит, что она может содержать ошибки в логике, потому что вы неправильно отфильтровали данные для показа пользователю. Но она не будет падать, потому что вы не получили данные из БД, сервер вернул вам не тот ответ, на который вы рассчитывали, или пользователь ввел дату своего рождения строкой, а не числом.

Не могу сказать, что компиляция swift кода может отловить все баги: например, утечку памяти допустить легко. Но строгая типизация и Optional хорошо защищают от множества глупых ошибок. Главное — ограничить принудительное извлечение.

Требования

Программирование

Естественно, прояснить основные принципы в программировании и изучить Swift не представляется возможным в рамках одной или двух статей. Так что я предполагаю, что вы уже имеете некоторый опыт в программировании. Ruby, PHP или JavaScript являются хорошей отправной точкой для изучения Swift. Если у вас был ранее опыт web программирования, тогда после прочтения двух последующих статей у вас не должно возникнуть проблем в изучении основ Swift.

Swift

В двух последующих статьях я расскажу о «песочнице», новой фиче, появившейся в Xcode 6. Также мы рассмотрим основные структуры языка программирования Swift, такие как переменные, константы, типы данных, включая множества, массивы и словари.

Также вы изучите основы, касающиеся классов и структур. В следующей статье мы углубимся в изучение замыканий, функций, протоколов и контроле доступа. Всё это должно дать достаточно для понимания языка, чтобы успешно пройти оставшиеся статьи в данном цикле уроков.

Objective-C

Строго говоря, C и Objective-C не являются обязательными для изучения, если вы заинтересованы в разработке для iOS платформы. При этом, множество фреймворков, которые мы будем использовать для разработки iOS приложений, написаны на C и Objective-C. Так что я все равно так или иначе буду говорить о C и Objective-C. Однако же не стоит переживать, я позабочусь о том, чтобы вы могли без труда понимать всё, что необходимо для того, чтобы держать вас на тропе к вашей цели — становлению iOS разработчиком.

Xcode и Swift

На протяжении данной серии уроков мы будем использовать Xcode 7.1 и Swift 2.1. Если вы используете более раннюю версию Xcode, следует иметь ввиду, что вы не сможете работать со Swift 2.1. Swift продолжает стремительно меняться и синтаксис эволюционирует с каждой новой итерацией языка. Так что настоятельно рекомендуется все-таки использовать Xcode 7.1, который включает в себя Swift 2.1.

Классы и Методы

Одна из самых частых вещей, которую вы будете делать при разработке приложении на Swift — создание классов и методов. Удалите все, что написали ранее в файл нашего playground’а.

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

Для того чтобы создать класс, нужно поставить ключевое слово class, после которого написать его имя. После чего, нужно написать фигурные скобки для тела класса.

Если вы создаете субкласс, то после имени субкласса, вам нужно поставить двоеточие и имя суперкласса. В отличии от Objective-C в Swift вам не нужно постоянно писать суперкласс NSObject или что-то другое. Добавьте в фигурные скобки следующее:

После того, как вы добавите этот код, вы получите несколько ошибок, не переживайте, мы скоро их исправим.

Свойства класса создаются точно так же как и просто константы или переменные. Здесь мы создали три константных свойства: первое — счет после уплаты налогов, второе — налоги, третье — счет до уплаты налогов.

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

Если нет желания указывать начальное или исходное значение, то необходимо объявить свойства как опционалы, но это совсем другая история, то есть туториал.

Теперь добавьте следующий блок в фигурные скобки:

Тут мы создали инициализатор для класса, который принимает два параметра. Инициализатор всегда называется ключевым словом init в Swift. Вы можете создать несколько инициализаторов, если вам так угодно, вот только они должны принимать разные параметры.

Смотрите, мы дали параметрам этого метода такие же имена как и свойствам класса. И, чтобы их не путать, мы поставили ключевое слово self.

Теперь, у нас нет никакого конфликта имен для свойства subtotal, так что нам больше не нужно добавлять self, потому что компилятор уже автоматически выводит его, когда это нужно. Для тех, кому не все равно откуда взялось subtotal = total / (taxPct + 1) поясним:

Теперь, добавьте следующий блок кода в фигурные скобки (после предыдущего в фигурных скобках):

Поясним, что для написания метода нам пригодится ключевое слово func. Когда мы создаем метод, мы должны указывать тип параметров явно и выходной тип метода, после результирующей стрелки ->.

Эта функция определяет размер налога, путем перемножения процента на общую сумму.

Теперь, добавляем следующий блок и снова в самый конец фигурных скобок:

Вот этот блок, когда представляет из себя новый метод, который выводит на экран три возможных варианта чаевых. Когда вы вызываете метод класса, то первый параметр необязательно должен иметь имя, но остальные должны.

Также, обратите внимание, что интерполяция строки не имеет ограничения в выводе переменных. Вы можете вписывать туда все что угодно — любые операции, которые только придут вам в голову!. Теперь, давайте добавим последний кусок кода в самый конец, после фигурных скобок:

Теперь, давайте добавим последний кусок кода в самый конец, после фигурных скобок:

Наконец-то, мы создали подобие калькулятора для чаевых Вот, что в итоге у нас должно было получиться в нашей «игровой площадке»:

Проверьте ваш Assistant Editor на наличие результата:

Операторы

Стандартная библиотека Swift определяет ряд операторов для вашего использования, многие из которых обсуждаются в Базовые операторы и Продвинутые операторы. В настоящем разделе описывается, какие символы могут быть использованы для определения пользовательских операторов.

Пользовательские операторы могут начинаться с одного из символов ASCII: , =, -, +, !, *, %, <, >, &, |, ^, ?, или ~, или одного из символов Unicode, которые мы разберем позднее (которые, среди других, включают в себя символы из Математических Операторов, Смешанные Символы и Графические метки блоков Unicode. После первого символа, использование других символов Unicode также является допустимым.

Можно также определить пользовательские операторы, которые начинаются с точки (.). Эти операторы могут содержать дополнительные точки, такие как .+.. Если оператор не начинается с точки, он не может содержать точку в другом месте. Например, +.+ Рассматривается как оператор +, за которым следует оператор +..

Вы также можете определить пользовательские операторы, содержащие знак вопроса (?), но они не могут состоять только из одного символа — знака вопроса. И хотя операторы и могут содержать восклицательный знак (!), но постфиксные операторы не могут начинаться знаком вопроса, либо восклицательным знаком.

Заметка

Токены =, ->, //, /*, */, ., префиксные операторы <, &, и ?, инфиксный оператор ?, и постфиксные операторы >, !, и ? зарезервированы. Эти токены не могут быть перезагружены, и не могут быть использованы в качестве пользовательских операторов.

Пробелы вокруг оператора используется для того, чтобы понять, используется ли оператор в качестве префиксного оператора, постфиксного оператора или бинарного оператора. Такое поведение представлено в следующих правилах:

  • Если у оператора пробелы по обеим сторонам или их нет вообще, то он рассматривается как бинарный оператор. Например, оператор +++ в a+++b и a +++ b рассматривается как бинарный оператор.
  • Если у оператора пробелы только слева, он рассматривается как префиксный унарный оператор. В качестве примера, оператор +++  в a +++b  рассматривается как префиксный унарный оператор.
  • Если у оператора пробелы только на правой стороне, он рассматривается как постфиксный унарный оператор. Например, оператор +++ в a+++ b рассматривается как унарный постфиксный оператор.
  • Если у оператора нет вообще пробелов слева, но за ним сразу идет точка (.), то это унарный постфиксный оператор. Например, оператор +++ в a+++.b рассматривается как унарный постфиксный оператор (a+++ .b, а не a +++ .b).

В целях следования настоящим правилам, символы (, , и { перед оператором, символами ), , и }, после оператора, и символов ,, ;, и также рассматриваются в качестве пробелов.

Для вышеуказанных правил существует одно “но”. Если у предопределенного оператора ! или ? нет пробелов слева, то он рассматривается как постфиксный оператор, независимо от того, имеет ли он пробел справа. Чтобы использовать ? в качестве оператора опциональной цепочки, то у него не должно быть пробела слева. Для того, чтобы использовать его в тернарном операторе (? ), у него должны быть пробелы с двух сторон.

В некоторых конструкциях, операторы, начинающиеся с < или > могут быть разделены на два или более токена. То, что осталось обрабатывается так же, и может быть разделено снова. В результате, нет необходимости использовать пробел для устранения неоднозначности между символами замыкания > в конструкциях, таких как Dictionary<String, Array<Int>>. В этом примере, символы замыкания > не рассматриваются как один токен, который затем может быть неправильно истолкован в качестве a оператора побитового смещения >>.

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