Swift (мова програмування)
Swift — багатопарадигмова компільована мова програмування, розроблена компанією Apple для того, щоб співіснувати з Objective C і бути стійкішою до помилкового коду. Swift була представлена на конференції розробників WWDC 2014[1]. Мова побудована з LLVM компілятором, включеного у Xcode 6 beta. Безкоштовний посібник мови програмування Swift доступний для завантаження у магазині iBooks[2].
Swift (мова програмування) | |
---|---|
Парадигма | Багатопарадигмова (протокол-орієнтована, об'єктно-орієнтована, функційна, імперативна, блочно-структурована) |
Дата появи | 2014 |
Творці | Кріс Латнер та Apple Inc. |
Розробник | Apple Inc. |
Останній реліз | 5(25 березня 2019; 10 місяців назад) (5 грудня 2017 ) |
Система типізації | статична, сувора, вивід типів |
Під впливом від | Objective-C, Rust, Haskell, Ruby, Python, C#, CLU, |
Вплинула на | Rust |
Операційна система | iOS, macOS, watchOS, Linux, tvOS |
Ліцензія | Apache License (починаючи з Swift 2.2), Проприєтарна (до версії Swift 2.2) |
Звичайні розширення файлів |
.swift |
Репозиторій вихідного коду | github.com/apple/swift |
Вебсайт | swift.org |
Swift у Вікісховищі |
Компілятор Swift побудований з використанням технологій вільного проєкту LLVM. Swift успадковує найкращі елементи мов C і Objective-C, тому синтаксис звичний для знайомих з ними розробників, але водночас відрізняється використанням засобів автоматичного розподілу пам'яті і контролю переповнення змінних і масивів, що значно збільшує надійність і безпеку коду.
При цьому Swift-програми компілюються у машинний код, що дозволяє забезпечити високу швидкодію. За заявою Apple, код Swift виконується в 1.3 рази швидше коду на Objective-C. Замість збирача сміття Objective-C в Swift використовуються засоби підрахунку посилань на об'єкти, а також надані у LLVM оптимізації, такі як автовекторизація.
Мова також пропонує низку сучасних методів програмування, таких як замикання, узагальнене програмування, лямбда-вирази, кортежі і словникові типи, швидкі операції над колекціями, елементи функційного програмування. Основним застосуванням Swift є розробка користувацьких застосунків для macOS, iOS, tvOS, watchOS з використанням тулкіта Cocoa і Cocoa Touch. При цьому Swift надає об'єктну модель, сумісну з Objective-C. Сирцевий код мовою Swift може змішуватися з кодом на С і Objective-C в одному проєкті.
Swift щільно інтегровано до власницького середовища розробки Xcode, проте може бути викликано з терміналу, що уможливлює її використання на операційний системах, відмінних від macOS, наприклад, на Linux.
Окремо варто відзначити, що Swift від компанії Apple не варто плутати з досить давно розроблюваною скриптовою мовою Swift, націленої на багатонитеве програмування і поставленого під вільною ліцензією Apache.
Історія
Розробку мови Swift почав Chris Lattner у співпраці із багатьма іншими програмістами. Ідеї для Swift запозичені із таких мов програмування як «Objective-C, Rust, Haskell, Ruby, Python, C#, CLU, та багатьох інших із списку».[3] 2 червня 2014 року на Всесвітній конференції розробників вперше офіційно було представлено додаток, написаний мовою Swift.[4] Бета версія мови стала доступна для зареєстрованих розробників на сайті компанії, але в Apple не гарантували, що представлена версія буде сумісна із фінальною версією.[4]
Також було представлено безплатний посібник по використанню Swift, обсягом 500 сторінок, на сервісі IBooks.[5]
Версія Swift 1.0 була випущена 9 вересня 2014 року разом із «Gold Master»-версією Xcode 6.0 для iOS.[6] Swift 1.1 було презентовано 22 жовтня 2014 року разом із Xcode 6.1.[7] Swift 1.2 презентовано 8 квітня 2015 із Xcode 6.3.[8] Swift 2.0 презентовано на WWDC 2015. Оголошення про розробку та подальші плани Swift 3.0 відбулось 3 грудня 2015.[9]
У грудні 2015 року IBM оголосила про запуск сайту Swift Sandbox, який дозволяє розробникам писати код в одному полі та бачити результат виконання в іншому.[10] У січні 2018 Swift Sandbox було визнано застарілим.
В квітні 2016 року журналісти видання The Next Web повідомили, що Google розглядає можливість поліпшити рівень підтримки або Swift або Kotlin платформою Android[11]. Згодом саме мова Kotlin стала рекомендованою для розробки на платформі Android.[12]
Під час WWDC 2019 Apple анонсувала SwiftUI – новий UI-фреймворк для програмних платформ Apple, заснований на принципах декларативного дизайну.
У квітні 2020 року вийшов відкритий неофіційний переклад посібника по використанню Swift.[13]
З версії 5.3, яка вийшла у вересні 2020 року, почалася підтримка Swift для Windows.[14]
Особливості
Swift розроблявся як заміна Objective-C, як мова, що залучає сучасні підходи у проєктуванні програмних систем та має простий синтаксис.
З точки зору синтаксису, Swift наближено до інших популярних ООП-мов, таких як C# та Java. Використовується виклик методів через крапку, для декларування класів та структур використовуються фігурні дужки.
Для управління пам’яттю використовується ARC[15] (автоматичний лічильник посилань). Загалом відсутня система явного управління пам’яттю, проте можливе явне створення небезпечних вказівників для взаємодії з кодом на C та Objective-C.
За замовчуванням, посилання не можуть набувати нульових значень, які в інших мовах позначають відсутність об’єкта. Натоміть, використовуються опціонали – спеціальний тип даних, який явно вказує на відсутність об’єкту за ім’ям.[16]
Екземпляри класів та функції є типами, що передаються за посиланням (типи-посилання), а екземпляри структур, перелічувань та кортежів передаються за значенням (типи-значення).[17]
Підтримуються протоколи, успадкування, узагальнені типи та функції. Типізація статична, проте інформація про типи певною мірою доступна на етапі виконання.
Для програмних платформ Apple використовується окрема версія Swift, яка тісно інтегрована з Objective-C та має підтримку переважної більшості функцій цієї мови, у тому числі її рантайму, на базі якого засновані ключові фреймворки та бібліотеки від Apple.
Можливості для метапрограмування на етапі виконання практично відсутні, але існують конструкції для варіативної компіляції, які враховують цільову платформу та її версію, а також інші атрибути, задані користувачем.
Змінні та константи
Будь-яке значення має бути ініціалізовано до свого першого використання.
Константою у Swift є значення, що визначається лише один раз. Значення константи не обов’язково має бути відмомим та етапі компіляції, так, її може бути створено під час створення об’єкта чи у результаті виконання умовних операторів.
Змінна може бути модифікована необмежену кількість разів.
Управління пам'яттю
Використовується декілька способів управління пам’яттю: ARC (автоматичний лічильник посилань), управління пам’яттю для типів значень, ручне управління пам’яттю.
Управління пам’яттю для типів-значень
Пам’ять для типів-значень (вбудовані примітивні типи, структури, перелічування, кортежі) може бути виділена на стеку або на купі. На стеку вона виділяється у тому випадку, якщо значення не міститься у типі-посиланні та не містить тип-посилання. У такому разі на етапі компіляції може бути обрахована кількість пам’яті для виділення, а також визначені точки виділення та звільнення пам’яті. В іншому разі відбувається виділення пам’яті на купі, яке є повільнішим та обраховується під час виконання програми.[18]
З точки зору користовуача, структури створюються під час першої ініціалізації, копіюються під час кожної операції присвоєння та вивільняються після виходу з зони видимості. Фактично використовується відкладене копіювання, тобто копіювання після першої зміни. Також з точки зору семантики, зміна будь-якого поля структури є створенням нової структури на базі старої зі зміненим полем, тому неможливо змінити значення поля структури, визначеної константою.
Для передачі структури за посиланням використовується ключове слово inout
, проте посилання на структури не можна зберігати безпечно.
Управління пам’яттю за допомогою ARC
З точки зору користувача, типи-посилання (класи) створюються під час першої ініціалізації, передаються за посиланням під час операції прсвоєння та вивільняються з пам’яті тоді, коли на об’єкт більше немає посилань.
Кожне значення типу-посилання містить лічильник, значення якого дорівнює 1 на момент створення. Під час створення кожного сильного посилання на об’єкт лічильник збільшується на 1. Під час вилучення посилання, значення лічильника зменшується на 1. Коли значення лічильника стає рівним 0, об’єкт вивільняється з пам’яті.
Можливе утворення циклів посилань, коли два об’єкти, що вийшли з області видимості, посилаються одне на одного і утримують одне одного в пам’яті. Для уникнення таких циклів використовуються слабкі посилання, які не враховуються у роботи лічильника. Слабкі посилання позначаються ключовими словами weak
та unowned
.
Ручне управління пам'яттю
Можливе створення небезпечних вказівників, управління створенням на вивільненням яких здійснюється вручну, однак кожен з типів небпзечних вказівників не має всього набору можливостей, які є у такого вказівника у мові C.
Також для пришвидшення роботи можуть бути використані об’єкти NSAutoreleasePool, які дозволяють звільнити деяку кількість об’єктів у визначений програмістом час.
Інкапсуляція
Swift підтримує такі області видимості:
private
– видимість лише у межах типу;fileprivate
– видимість лише у межах файлу;default
(не позначається) – видимість у межах модуля;public
– видимість поза модулем; без можливості перевизначення для полів та успадкування для класу;open
– видимість поза модулем із можливостямі перевизначення для полів та успадкування для класу;
У Swift немає аналога protected
(видимість тільки для класів-нащадків у інших мовах програмування), fileprivate
часто використовується для зв’язування типів та розширень зі збереженнях загальної інкапсуляції на рівні файлу.
Поля та функції типу
- Обчислювана властивість – синтаксичний цукор для функції без аргументів, виклик якої виглядає як доступ до поля;
- Лінива властивість – обчислюється під час першого виклику і далі є сталою;
- Властивість – може зберігати у собі значення або його відображати. Можна встановити функції, які будуть виконуватися під час отримання значення (
get
), під час присвоєння (set
), до та після присвоєння (willSet
таdidSet
); - Функція – не зберігає стану, може мати від 0 аргументів та повертати результат;
Будь-які функції та поля, крім лінвих, можуть бути статичними, тобто бути полем або функцією типу, а не екземпляру типу. При цьому існує два позначення статичності: class
для полів, що можуть бути перевизначені та static
для полів, які не можуть бути перевизначені у класі-нащадку.
Також будь-яке поле може бути позначене як final
, тобто поле, що не може бути перевизначене, static
та final class
є синонімічними для позначення поля класу.
Узагальнення
Swift підтримує розвинуту систему узагальнень. Будь-який тип чи функція може бути узагальнено за допомогою параметрів, що додаються після імені у кутових дужках. Для таких типів може бути встановлено обмеження на рівність деяким інших типам, імплементацію протоколів чи на успадкування від деяких типів. При цьому узагальнення для протоколів, так звані асоційовані типи, можуть мати навіть вимогу на імплементацію цього ж протоколу рекурсивно. Це породжує теоретичну Тюрінг-повноту для узагальнень, яка не реалізована у реальних компіляторах та її реалізація не планується. Встановлено обмеження на кількість таких вкладень.
Типи-перелічування
Типи-перелічування можуть бути представлені рядками, цілими числами та числами з рухомою комою. Якщо вони не представлені цими типами, кожен варіант перелічування може мати асоційовані з ним значення, як анонімні, так і поіменовані. Для роботи з типами-перелічування використовуються оператори if case
, guard case
, for case
та switch
.
Окремим випадком перелічувань є опціонали. Це типи, що замінюють у Swift концепцію нульового указника на позначення відсутності об’єкта. Тип Optional
складається з двох варіантів: none
та some(T)
, тобто може приймати значення або відсутності, або наявності об’єкта. Розкриття опціоналу називається отримання його значення. Для цього типу впроваджена велика кількість синтаксичного цукру (ланцюжок опціоналів, примусове та умовне розкриття опціоналу оператор ??
для позначення альтернативи при розкритті значення none. Для позначення змінних-опціоналів є спеціальний літерал, також є літерал, що вказує на розкритість значення за замовчуванням (за відсутності значення станеться помилка).
Розширення
У Swift можна створювати розширення типів. У них можна визначити додаткові функції та поля для об’єктів типу та самих типів, проте неможливо зберігати значення.
Можна розширювати також окремі випадки узагальнених типів (наприклад, встановти, що розширення стосується лише типу, що параметризовано значенням, яке відповідає певному протоколу).
Успадкування
Система успадкування Swft характеризується такими особливостями:
- Успадкування підтримується лише для класів;
- Множинне успадкування неможливе;
- Можливе перевизначення як полів класу, так і полів об’єкту класу;
Імплементація протоколів
Протокол у Swift визначає деякі вимоги до типу. Ці вимоги можуть стосуватися наявності функцій у типі, змінних типу, необхідності визначення інших типів даним типом (асоційовані типи), класу, від якого має успадкуватися клас чи інших протоколів, які має імплементувати клас.
Будь-який тип у Swift може імплементувати протокол. Також імплементація протоколу для будь-якого типу можлива за допомогою розширення.
Змінні, що мають тип протоколу, посідають окреме місце у системі типів Swift. Такі змінні називаються екзистенціалами та до них використовується динамічна диспетчерізація. Створення екзистенціалів неможливо для протоколів, які мають вимоги до асоційованих типів, у тому числі і посилаються на тип-нащадок Self у своїх вимогах. Причина цього полягає в тому, що динамічна диспетчерізація у Swift не може бути використана для визначення таких пов’язаних типів.
Приклад коду
// це приклад однорядкового коментаря
/* це також коментар,
але написаний в декілька рядків */
/* багаторядкові коментарі
/* можуть бути вкладені! */
тому ви можете поміщати коментарі в блоки
*/
/* оголошення змінних у Swift починається із службового слова "var", після якого повинні
бути ім'я змінної, тип змінної та початкове значення */
var explicitDouble: Double = 70
// якщо тип змінної не вказано, Swift обере його автоматично на основі початкового значення
var implicitInteger = 70
var implicitDouble = 70.0
var 国 = "日本"
/* оголошення константи у Swift починається із службового слова "let", після якого повинні
бути ім'я змінної, тип змінної та початкове значення */
let numberOfBananas: Int = 10
// якщо тип константи не вказано, Swift обере його автоматично на основі початкового значення
let numberOfApples = 3
let numberOfOranges = 5
// значення змінних та констант можуть бути вставлені у рядки (змінні типу string) наступним чином
let appleSummary = "I have \(numberOfApples) apples."
let fruitSummary = "I have \(numberOfApples + numberOfOranges) pieces of fruit."
// оголошення масиву даних
var fruits = ["mango", "kiwi", "avocado"]
// приклад оператора if; функцій .isEmpty, та .count
if fruits.isEmpty {
print("Фрукти відсутні у масиві даних.")
} else {
print("В масиві даних є \(fruits.count) фруктів")
}
// приклад оголошення "словника" (dictionary ) з 4 елементів, кожен із яких містить ім'я та вік
let people = ["Anna": 67, "Beto": 8, "Jack": 33, "Sam": 25]
// використовуючи можливості мови Swift, ми надрукуємо обидва значення в єдиному циклі
for (name, age) in people {
print("\(name) is \(age) years old.")
}
// оголошення методів починається із службового слова "func"
// тип результату описується після "->"
func sayHello(personName: String) -> String {
let greeting = "Hello, " + personName + "!"
return greeting
}
// як вивести в консолі словосполучення "Hello, Jane!", використовуючи вище описаний метод
print(sayHello("Jane"))
Примітки
- Apple announces Swift, a new programming language for iOS.
- The Swift Programming Language
- Lattner, Chris (3 червня 2014). Chris Lattner's Homepage. Chris Lattner. Процитовано 3 червня 2014. «I started work on the Swift Programming Language in July of 2010. I implemented much of the basic language structure, with only a few people knowing of its existence. A few other (amazing) people started contributing in earnest late in 2011, and it became a major focus for the Apple Developer Tools group in July 2013 [...] drawing ideas from Objective-C, Rust, Haskell, Ruby, Python, C#, CLU, and far too many others to list.»
- Platforms State of the Union, Session 102, Apple Worldwide Developers Conference, June 2, 2014
- The Swift Programming Language. Apple. 2 червня 2014. Процитовано 2 червня 2014.
- Swift Has Reached 1.0. 9 вересня, 2014. Процитовано 10 вересня 2014.
- Xcode 6.1 Release Notes. 22 жовтня 2014. Процитовано 4 березня 2015.
- Xcode 6.3 Release Notes. 8 квітня 2015. Процитовано 4 березня 2015.
- http://thenextweb.com/apple/2015/12/03/apple-has-big-plans-for-swift-3-0-and-beyond-including-api-changes-and-working-with-c/
- Mayo, Benjamin (4 грудня 2015). Write Swift code in a web browser with the IBM Swift Sandbox. 9to5Mac (амер.). Процитовано 20 серпня 2021.
- Nate Swanner (7 квітня 2016). Google may be considering Swift for use on Android. The Next Web. https://www.facebook.com/thenextweb. Процитовано 11 квітня 2016.
- Kotlin is now Google’s preferred language for Android app development. TechCrunch (амер.). Процитовано 20 серпня 2021.
- Володько, В'ячеслав. Мова програмування Swift. book.swift.org.ua (Українська). Процитовано 20 квітня 2020.
- Inc, Apple (22 вересня 2020). Introducing Swift on Windows. Swift.org (англ.). Процитовано 20 серпня 2021.
- Automatic Reference Counting — The Swift Programming Language (Swift 5.5). docs.swift.org. Процитовано 20 серпня 2021.
- The Basics — The Swift Programming Language (Swift 5.5). docs.swift.org. Процитовано 20 серпня 2021.
- Structures and Classes — The Swift Programming Language (Swift 5.5). docs.swift.org. Процитовано 20 серпня 2021.
- Bakshi, Neel (25 березня 2021). Classes vs. Structs in Swift — Basics and Memory Management. Medium (англ.). Процитовано 23 серпня 2021.