SWIFT (програмен език)

от Уикипедия, свободната енциклопедия
Направо към: навигация, търсене
Swift
Swift logo with text.svg
Парадигма Multi-paradigm (object-oriented, functional, imperative, block structured)
Реализиране през 9 септември 2014 г.;
преди 2 години
 (2014-09-09)[1]
Автор Chris Lattner and Apple Inc.
Софтуерен разработчик Apple Inc.
Стабилна реализация 2.2.1
май 3, 2016 (2016-05-03)/ преди 2 месеца
Типизация на данните Static, strong, inferred
Повлиян от Objective-C, Rust, Haskell, Ruby, Python, Scala, C#, CLU,[2] D[3]
Повлиява Rust[4]
Операционна система OS X, iOS, Darwin, Linux, FreeBSD
Софтуерен лиценз Proprietary software[5]
Файлово разширение .swift
Уебсайт swift.org

Суифт (на английски: Swift) е много-парадигмен компилируем програмен език, създаден от „Apple“ за разработване на приложения за iOS и Mac. Представен за първи път на Световната Конференция за Софтуерни Разработчици (WWDC Worldwide Developers Conference) през април 2014, Swift е разработен за Cocoa и Cocoa Touch. Проектиран е по такъв начин, че да помага на разработчиците при създаването на по-безопасен и надежден код като отстранява и избягва цели категории разпространени програмни грешки. Swift може да се интегрира във вече създадени приложения благодарение на възможността за съвместното му използване с код, написан на Objective-C.

История[редактиране | редактиране на кода]

Разработването на Swift започва през 2010 от Крис Латнър, като в проекта са се включили още много други разработчици. Swift е взаимствал доста идеи от други програмни езици като Objective-C, Rust, Haskell, Ruby, Python, C#, CLU и др. Първото приложение написано на програмния език Swift е представено официално на 2 юни 2014.

На 9 септември 2014 е представена финалната версия на Swift 1.0 и Xcode 6.0 за iOS. Swift 1.1 е пуснат на пазара на 22 октомври 2014, заедно с Xcode 6.1.

Характеристики[редактиране | редактиране на кода]

Swift е заместител на езика Objective-C. Разработен е на базата на съвременните теоретични концепции на програмирането, които водят до много по-опростен синтаксис на езика. По време на представянето му е описан като „Objective-C без C“.

По подразбиране Swift не създава указатели ( pointers) и други небезопасни обекти, за разлика от Objective-C, който широко използва указатели ( pointers) за референция към инстанции на обекти. Освен това, синтаксисът за извикване на методи на Objective-C е заменен с точкова нотация и именно пространство, по-познати на програмистите от други обектно-ориентирани езици като JavaScript, Java или C#. Swift въвежда използването на true named parameters, но запазва някои основни концепции от Objective-C като протоколи, затваряне (closures) и категории, като много често замества стария синтаксис с нова по-изчистена версия, позволявайки на тези концепции да бъдат използвани и върху други структури на езика като енумерациите.

Типове данни, променливи и опционални типове[редактиране | редактиране на кода]

В Cocoa и Cocoa Touch много основни класове бяха част от библиотеката Foundation Kit library. „Obj-C“ използваше така наречената „синтактична захар“, при която един обект се създава и след това се променя чрез извикването на друг метод. Например конкатенацията на два низа от класа NSStrings изискваше извикването на следния метод: NSString *str = @„hello,“; str = [str stringByAppendingString:@" world"]; В Swift много от основните типове данни са включени в стандартните библиотеки на езика и могат да бъдат променяни директно. Например символните низове са свързани с класа NSString (когато Foundation библиотеката е импортирана) и могат да бъдат долепени чрез оператора +. Горният пример изглежда по следния начин: var str = "hello," str += " world" Библиотеката Foundation Kit почти винаги включваше две версии на основните си класове: версия, при която те могат да бъдат променяни по време на изпълнение на програмата и такава, при която те могат да бъдат създадени и прочетени, но не могат да бъдат променяни. Swift остава верен на тази традиция по малко по-обобщаващ начин, приложим за всеки числов тип данни, а именно: стойността се декларира като констатнта и чрез използването на ключовата дума „let“ се превръща в тип, който не може да бъде променян. Не е необходимо константата да бъде декларирана още в началото на програмата. Стойности, които могат да бъдат променяни се декларират чрез ключовата дума“ var“.

Друга особеност на Swift са опционалните типове (optional types), които позволяват референции или стойности да действат по начин подобен на основните шаблони в C, където един указател (pointer) сочи или към стойност или е „null“. Това предполага, че неопционалните типове, не водят до „null-pointer error“. Опционалните типове се създават с помощта на така наречения опционален механизъм (Optional mechanism)—за създаването на цяло число (Integer), което е „nullable“ се използва декларация подобна на var optionalInteger: Optional<Int>. Подобно на C#, опционалната променлива може да бъде означена с поставянето на въпросителен знак след името на променливата: var optionalInteger: Int?. Променливи или константи, означени като опционални или имат стойност от съответния тип или са „nil“. Swift поддържа три нива за контрол на достъпа до части от кода: публично (public), вътрешно (internal) и частно (private). За разлика от много други обектно-ориентирани езици тези нива игнорират наследствената йерархия (inheritance hierarchies). Частен достъп означава, че даден обект е достъпен само във „source“ файла, в който е дефиниран. При вътрешния достъп обектите могат да бъдат достъпени само в рамките на модула, в който е дефиниран „source“ файла, а публичния достъп предоставя достъп от всеки модул. Решението да се избегне традиционния „защитен“ обхват среща доста критики.

Библиотеки, runtime и development[редактиране | редактиране на кода]

Swift използва същата „runtime“ система като вече съществуващата от Objective-C, но изисква iOS 7 / OS X 10.9 или по-висока версия. Кодът написан на Swift и Objective-C може да бъде използван в една единствена програма. За разлика от кодът, написан на C обаче, код написан на C++ не може да бъде използван директно от Swift. Необходимо е да се създаде „обвивка“ (wrapper) между Swift и C++. При Objective-C, Swift има значителен достъп до обектния модел и може да бъде използван като подклас (subclass), да разширява и използва код написан на Objective-C code за да осигури поддръжка на протокола.

За да подпомогне писането на такива програми и повторното използване на вече съществуващ код Xcode 6 предлага полу-автоматична система, която създава и поддържа „bridging header“, който показва код написан на Objective-C в Swift. Всъщност това е допълнителен header файл, който просто дефинира или вмъква всички Objective-C символи нужни за кода, който ще се пише на Swift. В кода, който се пише на Swift могат да се използват типове, функции и променливи, които са декларирани в кода, написан на С. Обратното също е възможно чрез вмъкване на символите от Swift от автоматично поддържания header файл в Objective-C декларациите. Например, ако имаме смесен проект наречен „MyApp“ файлът съдържащ код написан на Objective-C може да достъпва класовете или функциите от Swift файла със следния код #import „MyApp-Swift.h“. Не всички символи са достъпни използвайки този механизъм обаче—например generic types, необектните опционални типове (non-object optional types), някои енумерации и дори Unicode идентификатори могат да направят символите недостъпни за Objective-C.

Swift има ограничена поддръжка на атрибути, метаданни четени от средата за разработка, които незадължително са част от компилирания код. Подобно на Objective-C, атрибутите използват синтаксисът. Пример за такъв атрибут е @IBOutlet, който обозначава дадена стойност в кода като „outlet“, достъпен за използване в рамките на Interface Builder (IB). „Outlet“ е средство, което обвързва стойността с обект от кода.

Управление на паметта (Memory management)[редактиране | редактиране на кода]

Swift използва система за автоматично броене на референции (Automatic Reference Counting или ARC) за управление на паметта. Един от проблемите с ARC е вероятността да се създаде цикъл от референции (strong reference cycle), при който инстанции на два различни класа съдържат референции един към друг, което е причина да бъдат свързани в паметта и да не могат да бъдат „освободени“ никога. Това може да бъде избегнато чрез използването на слаби и непритежаеми ключови думи (weak and unowned keywords). Обикновено за връзката родител-дете (parent-child) се използва силна референция докато за дете-родител (child-parent) се използва или слаба референция, където родителите и децата могат и да не бъдат свързани, или непритежаема където детето винаги има родител, но родителят може да няма деца. Слабите референции трябва да са опционни променливи, т.к могат да бъдат променяни и да станат „nil“.

Затваряне(closure) вътре в един клас също може да създаде цикъл от референции (strong reference cycle) заради self-references. Програмистът трябва да посочи кои self-references са слаби или непритежаеми в т.нар. capture list.

Дебъгване и други елемент[редактиране | редактиране на кода]

Дебъгването във Swift се извършва чрез read–eval–print- loop (REPL). Средата е доразвита с добавянето на нова концепция, наречена 'playgrounds'. 'Playgrounds' са интерактивни изгледи от Xcode средата, отразяващи в движение промените в кода. Timeline Assistant може да бъде използван за да покаже резултатите от изпълнението на програмата в анимирам вариант.

Прилики със Objective-C[редактиране | редактиране на кода]

  • Основните числови типове данни (Int, UInt, Float, Double)
  • Повечето оператори са взаимствани от С, но има и някои нови
  • Къдравите скоби (Curly braces) се използват за групиране на изрази.
  • Присвояването на стойност към променлива се извършва чрез знака за равенство, но за сравнение на две променливи се използват два последователни знака за равенство. Операторът „ ===“ проверява дали два елемента сочат към един и същи обект.
  • Условните конструкции и циклите (for, while, if, switch) са подобни, но имат и някои допълнителни функционалности, например цикълът for in обхожда всеки тип колекция, цикълът switch може да приема нецелочислени (non-integer) cases и др.

Разлики със Objective-C[редактиране | редактиране на кода]

  • Изразите не трябва да завършват със точка и запетая (;), въпреки че те трябва да се използват в случаите на няколко израза на един ред
  • Не се изискват хедър файлове (header files)
  • Силно типизиран език
  • Generic programming

Функциите са първокласни обекти.

  • Случаите в енумерациите (enumeration cases) могат да приемат асоциативен тип данни (алгебрични типове данни).
  • Операторите могат да бъдат предифинирани в класове (operator overloading).
  • Символните низове (strings) поддържат напълно Unicode. Повечето Unicode символи могат да бъдат използвани или в идентификатори или в оператори.
  • Липсва „exception handling“ (въпреки че може да бъде заместено с използването на затваряния ( closures) ).
  • Някои „странни поведения“ при езиците от фамиличта на C са променени:
  • Указателите не се показват по подразбиране. Не е необходимо разработчикът да запазва или маркира имена за рефериране или дерефериране (de-referencing).
  • Присвояванията не връщат стойност. Често срещана грешка е да се напише if (i=0). В случаите когато if (i==0) се получава грешка при компилиране (compile-time error).
  • Няма нужда от израза break в switch блоковете, т.к програмата преминава към следващия случай само ако е използван израза fallthrough.
  • Променливите и константите трябва да се инициализират и границите на масивите винаги се проверяват.
  • Overflows, които имат неопределено поведение за целте числа със знак в C, са включени в „run-time error“, но могат да бъдат разрешени чрез специалните аритметични оператори &+, &-, &*, &/ и &%. Атрибутите min и max са дефинирани за всички целочислени типове в Swift и могат да бъдат използвани за безопасна проверка за евентуални overflows.

Сравнение със Python[редактиране | редактиране на кода]

Python е един от езиците вдъхновил написването на Swift.

  • И двата езика използват средата за разработка Read–eval–print loop (REPL)
  • Условните конструкции и циклите са подобни (for, if, while)
  • Swift е компилируем език докато стандартния Python е интерпретируем език.
  • В Swift има някои по-комплексни променливи като UInt32, StringLiteralConvertible и т.н.
  • Swift използва къдравите скоби за групиране на изрази.
  • Python не използва ключовите думи var и let.

Example code[редактиране | редактиране на кода]

// this is a single line comment using two slashes.

/* this is also a comment,
   but written over multiple lines */

/* multiline comments
   /* can be nested! */
   so that you can block out code containing multiline comments
*/

// Swift variables are declared with "var" followed by a name, a type, and a value
var explicitDouble: Double = 70

// if the type is omitted, Swift will infer it from the variable's initial value
var implicitInteger = 70
var implicitDouble = 70.0
var  = "美國"

// Swift constants are declared with "let" followed by a name, a type, and a value
let numberOfBananas: Int = 10

// if the type is omitted, Swift will infer it from the constant's value
let numberOfApples = 3
let numberOfOranges = 5

// values of variables and constants can be interpolated in strings as follows
let appleSummary = "I have \(numberOfApples) apples."
let fruitSummary = "I have \(numberOfApples + numberOfOranges) pieces of fruit."

// in playgrounds, code can be placed in the global scope
println("Hello, world")

// define an array
var fruits = ["mango", "kiwi", "avocado"]

// example of if statement; .isEmpty, .count
if fruits.isEmpty {
    println("No fruits in my array.")
} else {
    println("There are \(fruits.count) items in my array")
}

// define a dictionary with four items, each with a person's name and age
let people = ["Anna": 67, "Beto": 8, "Jack": 33, "Sam": 25]

// now we use Swift's flexible enumerator system to extract both values in a single loop
for (name, age) in people {
    println("\(name) is \(age) years old.")
}

// functions and methods are declared with the "func" syntax
// the return type is specified with ->
func sayHello(personName: String) -> String {
    let greeting = "Hello, " + personName + "!"
    return greeting
}

// prints "Hello, Jane!"
println(sayHello("Jane"))

// parameter names can be made external and required for calling
// the external name can be the same as the parameter name by
// prefixing with an octothorpe (#)
// or can be defined separately.
func sayAge(#personName: String, personAge Age: Int) -> String {
    let result = "\(personName) is \(Age) years old."
    return result
}

// we can also specify the name of the parameter
println(sayAge(personName: "Jane", personAge: 42))

Вижте още[редактиране | редактиране на кода]

Източници[редактиране | редактиране на кода]

  1. Swift Has Reached 1.0. // Apple, 2014-09-09. Посетен на 2015-03-08.
  2. Lattner, Chris. Chris Lattner's Homepage. // Chris Lattner, June 3, 2014. Посетен на June 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.
  3. Building assert() in Swift, Part 2: __FILE__ and __LINE__ – Swift Blog -. // Apple Developer. Посетен на September 26, 2014. Swift borrows a clever feature from the D language: these identifiers expand to the location of the caller when evaluated in a default argument list.
  4. RFC for `if let` expression. // Посетен на December 4, 2014. The `if let` construct is based on the precedent set by Swift, which introduced its own `if let` statement.
  5. Lattner, Chris. Re: [LLVMdev [cfe-dev] [ADVERTISEMENT] open positions in Apple's Swift compiler team]. // June 11, 2014. Посетен на June 12, 2014. You can imagine that many of us want it to be open source and part of llvm, but the discussion hasn't happened yet, and won't for some time.

Външни препратки[редактиране | редактиране на кода]