Привет, Хабр! 2 июня все мы воочию могли наблюдать, как компания Apple начала творить революцию в стане Objective-C разработчиков, представив миру свой новый язык программирования – Swift. Вместе с этим, она выложила в открытый доступ небольшую документацию по языку, которую мы решили перевести, если на то будет спрос. Предлагаем вашему вниманию перевод первой главы. Если тема будет интересна, то мы продолжим публиковать перевод каждую неделю.
Оглавление
Добро пожаловать в Swift
О Swift
Введение в Swift
Language guide
The Basics
Basic Operators
String and Characters
Collection Types
Control Flow
Functions
Closures
Enumerations
Classes and Structures
Properties
Methods
Subscripts
Inheritance
Initialization
Deinitialization
Automatic Reference Counting
Optional Chaining
Type Casting
Nested Types
Extensions
Protocols
Generics
Advanced Operators
Language Reference
About the Language Reference
Lexical Structure
Types
Expressions
Statements
Declarations
Attributes
Patterns
Generic Parameters and Arguments
Summary of the Grammar
Trademarks
Добро пожаловать в Swift
О языке Swift
Swift – это новый язык программирования для разработки iOS и OS X приложений, который сочетает в себе все лучшее от C и Objective-C, но лишен ограничений, накладываемых в угоду совместимости с C. В Swift используются паттерны безопасного программирования и добавлены современные функции, превращающие создание приложения в простой, более гибкий и увлекательный процесс. Swift, созданый нами с чистого листа, – это возможность заново представить себе, как разрабатываются приложения.
Swift разрабатывался нами несколько лет. Основой нового языка программирования послужили существующие компилятор, отладчик и фреймворки. Мы упростили процесс управления памятью с помощью механизма автоматического подсчета ссылок – Automatic Reference Counting (ARC). Наши фреймворки также подверглись серьезной модернизации. Objective-C начал поддерживать блоки, литералы и модули – все это создало благоприятные условия для внедрения современных технологий. Именно эта подготовительная работа послужила фундаментом для нового языка программирования, который будет применяться для разработки будущих программных продуктов для Apple.
Разработчикам Objective-C Swift покажется знакомым. Он сочетает в себе читабельность именованных параметров и мощь динамической объектной модели Objective-C. Он открывает доступ к уже существующим фреймворкам Cocoa и совместим с кодом, написанным на Objective-C. Построенный на этой общей основе язык предлагает множество новых возможностей и унифицирует процедурные и объектно-ориентированные аспекты языка программирования.
Swift не отпугнет и начинающих программистов. Это первый мощный язык программирования, такой же понятный и увлекательный, как скриптовый язык. Он поддерживает так называемые playground-ы, которые позволяют программистам экспериментировать с кодом, видя результат в режиме реального времени без необходимости компилировать и запускать приложение.
Swift вобрал в себя все лучшее от современных языков и разработан с учетом обширного опыта компании Apple. Наш компилятор – синоним производительности, наш язык оптимизирован для разработки без оглядки на компромиссы. Он спроектирован таким образом, чтобы вы смогли легко разработать и ваше первое приложение «hello, world!», и даже целую операционную систему. Все это делает Swift важным инструментом для разработчиков и для самой компании Apple.
Swift – это новый фантастический способ создавать приложения для iOS и OS X, и мы продолжим развивать его, добавляя новый функционал и представляя новые возможности. Наша цель – амбициозна. И мы с нетерпением ждем, чтобы увидеть, что вы сумеете создать при помощи него.
Введение в Swift
По давней традиции первая программа на новом языке должна выводить на экран слова “Hello, world”
. С помощью Swift это делается так:
println("Hello, world")
Если вы когда-нибудь разрабатывали на C или Objective-C этот синтаксис должен казаться вам до боли знакомым – в Swift эта строчка кода является законченной программой. Вам больше не нужно импортировать отдельные библиотеки для обеспечения базового функционала вроде ввода/вывода в консоль или работы со строками. Код, написанный в глобальной области видимости, является точкой входа в программу, таким образом функция main
больше не нужна. Также обратите внимание на отсутствие точки с запятой в конце каждой строки.
Это введение содержит достаточно информации, чтобы начать писать код на Swift. Не переживайте, если вам будет что-то непонятно – мы все детально объясним в последующих главах.
Замечание
Для лучшего понимания материала мы рекомендуем использовать режим playground в Xcode. Playground позволяет вам видеть результат сразу в процессе редактирования кода без необходимости компилировать и запускать приложение.
Простые типы данных
Используйте let
для создания константы и var
для создания переменной. Тип константы указывать не нужно, вы можете присвоить ей значение лишь единожды.
var myVariable = 42
myVariable = 50
let myConstant = 42
Типы константы и переменной должны совпадать с типами присваиваемых им соответствующих значений. Однако это не означает, что вы должны напрямую указывать их тип. Компилятор автоматически определит тип константы и переменной при присваивании им значения. Так, в приведенном примере компилятор определит, что myVariable
имеет целочисленный тип.
Если же инициализатор отсутствует или не предоставляет достаточной информации, вы можете указать тип самостоятельно после переменной, разделив название и тип двоеточием:
let implicitInteger = 70
let inplicitDouble = 70.0
let inplicitDouble: Double = 70
Давайте поэкспериментируем
Создайте константу с типом Float и проинициализируйте ее числом 4.
Значения никогда не конвертируются в другой тип неявно. Если вам необходимо конвертировать значение в другой тип, делайте это явно:
let label = "The width is "
let width = 94
let widthLabel = label + String(width)
Давайте поэкспериментируем
Попробуйте удалить явное преобразование к типу String в последней строке. Какую ошибку вы получите?
Имеется более простой способ включения значений в строки: для этого заключите выражение в скобки и поставьте перед ними обратный слэш (). Пример:
let apples = 3
let oranges = 5
let appleSummary = "I have (apples) apples."
let fruitSummary = "I have (apples + oranges) pieces of fruit."
Давайте поэкспериментируем
Попробуйте использовать конструкцию()
и выведите на экран строку, включающую результат суммы двух целочисленных переменных и чье-нибудь имя.
При работе с массивами и ассоциативными массивами (словарями, dictionary) используются квадратные скобки ([]
):
var shoppingList = ["catfish", "water", "tulips", "blue paint"]
shoppingList[1] = "bottle of water"
var occupations = [
"Malcolm": "Captain",
"Kaylee": "Mechanic",
]
occupations["Jayne"] = "Public Relations"
Чтобы создать пустой массив или dictionary, используйте следующий синтаксис:
let emptyArray = String[]()
let emptyDictionary = Dictionary<String, Float>()
Для создания пустых массивов и словарей используйте []
и [:]
соответственно, – например, когда вы присваиваете новое значение переменной или передаете аргумент в функцию.
shoppingList = [] // Went shopping and bought everything.
Условия и циклы
Для создания условий используются операторы if
и switch
, для создания циклов – for-in
, for
, while
и do-while
. При этом выделять круглыми скобками условия и инициализирующие выражения необязательно, тогда как фигурные скобки обязательны.
let individualScores = [75, 43, 103, 87, 12]
var teamScore = 0
for score in individualScores {
if score > 50 {
teamScore += 3
} else {
teamScore += 1
}
}
teamScore
Условие внутри оператора if
должно быть логическим, это в частности означает, что выражение if score {…}
является ошибочным, поскольку здесь нет явного сравнения (например, с нулем).
Условный оператор if
можно использовать совместно с let
и var
для работы с константами и переменными, которые могут иметь значение nil
. Такие константы и переменные называются опциональными (то есть они могут либо принимать какое-либо значение, либо быть равны nil
). Чтобы создать опциональную переменную или константу добавьте знак вопроса (?
) после указания типа.
var optionalString: String? = "Hello"
optionalString == nil
var optionalName: String? = "John Appleseed"
var greeting = "Hello!"
if let name = optionalName {
greeting = "Hello, (name)"
}
Давайте поэкспериментируем
ИзменитеoptionalName
наnil
. Что вы видите на экране? Добавьте блокelse
для обработки случая, когдаoptionalName
равенnil
.
Если опциональное значение равно nil
, условие будет ложным и код в фигурных скобках после if
выполнен не будет. В противном случае переменной greeting
будет присвоено новое значение.
Оператор множественного выбора switch
поддерживает внутри себя множество других операторов сравнения и не ограничен лишь простыми сравнениями:
let vegetable = "red pepper"
switch vegetable {
case "celery":
let vegetableComment = "Add some raisins and make ants on a log."
case "cucumber", "watercress":
let vegetableComment = "That would make a good tea sandwich."
case let x where x.hasSuffix("pepper"):
let vegetableComment = "Is it a spicy (x)?"
default:
let vegetableComment = "Everything tastes good in soup."
}
Давайте поэкспериментируем
Попробуйте удалить условие по умолчанию. Какую ошибку вы получите?
После выполнения подходящего блока кода, программа покидает оператор switch
, не проверяя последующие условия. Таким образом вам не нужно вручную добавлять операторы прерывания (break
) в конце каждого блока case
.
Для перебирания элементов ассоциативного массива используйте оператор for-in
совместно с указанием пары имен для каждой пары ключ-значение.
let interestingNumbers = [
"Prime": [2, 3, 5, 7, 11, 13],
"Fibonacci": [1, 1, 2, 3, 5, 8],
"Square": [1, 4, 9, 16, 25],
]
var largest = 0
for (kind, numbers) in interestingNumbers {
for number in numbers {
if number > largest {
largest = number
}
}
}
largest
Давайте поэкспериментируем
Добавьте еще одну переменную, которая позволит выяснить, к какому из трех типов относится найденное максимальное число.
Оператор цикла while
позволяет выполнять блок кода внутри него до тех пор, пока условие не станет ложным. Условие также может быть указано после блока, который в таком случае будет выполнен по крайней мере один раз.
var n = 2
while n < 100 {
n = n * 2
}
n
var m = 2
do {
m = m * 2
} while m < 100
m
Оператор for
можно использовать для перебора последовательности чисел с помощью двух точек (..
) или с помощью инициализатора, условия и инкремента. Посмотрите, эти два цикла делают одно и то же:
var firstForLoop = 0
for i in 0..3 {
firstForLoop += i
}
firstForLoop
var secondForLoop = 0
for var i = 0; i < 3; ++i {
secondForLoop += 1
}
secondForLoop
При создании цикла используйте две точки (..
), если не хотите включать большее значение в диапазон, и три точки (…
), чтобы включить как меньшее, так и большее значения.
Функции и замыкания.
Для объявления функций используйте ключевое слово func
. Вызов функции производится через указание ее имени и списка аргументов в круглых скобках. Возвращаемый тип следует отделить от перечня формальных аргументов с помощью ->
.
func greet(name: String, day: String) -> String {
return "Hello (name), today is (day)."
}
greet("Bob", "Tuesday")
Давайте поэкспериментируем
Удалите параметр day. Вместо него добавьте переменную, обозначающую наименование подаваемого на обед блюда.
Если функция возвращает множество значений, следует использовать кортеж:
func getGasPrices() -> (Double, Double, Double) {
return (3.59, 3.69, 3.79)
}
getGasPrices()
Функции также могут иметь неопределенное число аргументов:
func sumOf(numbers: Int...) -> Int {
var sum = 0
for number in numbers {
sum += number
}
return sum
}
sumOf()
sumOf(42, 597, 12)
Давайте поэкспериментируем
Напишите функцию, позволяющую находить среднее арифметическое произвольного числа своих аргументов.
Функции могут вкладываться друг в друга. Вложенная функция может обращаться к переменным, объявленным во внешней функции. Используйте вложенные функции, чтобы привести в порядок код сложной или большой функции.
func returnFifteen() -> Int {
var y = 10
func add() {
y += 5
}
add()
return y
}
returnFifteen()
Функции являются объектами первого класса (first-class type), иными словами, функция в качестве свого результата может возвращать другую функцию.
func makeIncrementer() -> (Int -> Int) {
func addOne(number: Int) -> Int {
return 1 + number
}
return addOne
}
var increment = makeIncrementer()
increment(7)
Функция также может принимать другую функцию в качестве одного из аргументов.
func hasAnyMatches(list: Int[], condition: Int -> Bool) -> Bool {
for item in list {
if condition(item) {
return true
}
}
return false
}
func lessThanTen(number: Int) -> Bool {
return number < 10
}
var numbers = [20, 19, 7, 12]
hasAnyMatches(numbers, lessThanTen)
Функции являются частным случаем замыканий. Вы можете создать замыкание, не указывая его имени и окружив тело замыкания фигурными скобками ({}
). Для отделения аргументов и типа возвращаемого значения от тела замыкания используйте оператор in
.
numbers.map({
(number: Int) -> Int in
let result = 3 * number
return result
})
Давайте поэкспериментируем
Перепишите замыкание таким образом, чтобы оно возвращало ноль для всех лишних чисел.
Существует несколько техник, позволяющих делать замыкания более лаконичными. Если тип замыкания априори известен (например, это callback делегата), можно опустить указание типа его параметров и/или типа возвращаемого значения. Замыкания, состоящие из единственного выражения, неявно возвращают результат этого выражения.
numbers.map({ number in 3 * number })
В замыкании вместо указания имени переменной, вы можете использовать ее порядковый номер – это особенно полезно при написании коротких замыканий. Замыкание, являющееся последним аргументом функции, может быть передано в нее сразу после круглых скобок с перечнем остальных параметров.
sort([1, 5, 3, 12, 2]) { $0 > $1 }
Объекты и классы
Для создания класса используется зарезервированное слово class
. Члены класса объявляются точно так же, как и обычные константы и переменные. Более того, методы класса объявляются как обычные функции.
class Shape {
var numberOfSides = 0
func simpleDescription() -> String {
return "A shape with (numberOfSides) sides."
}
}
Давайте поэкспериментируем
Добавьте константу-член класса и метод класса, принимающую ее в качестве своего аргумента.
Чтобы создать экземпляр (объект) класса, достаточно добавить круглые скобки после названия класса. Доступ к методам и членам класса осуществляется через точку.
var shape = Shape()
shape.numberOfSides = 7
var shapeDescription = shape.simpleDescription()
В этом примере мы упустили одну важную деталь – конструктор класса, метод init
.
class NamedShape {
var numberOfSides: Int = 0
var name: String
init(name: String) {
self.name = name
}
func simpleDescription() -> String {
return "A shape with (numberOfSides) sides."
}
}
Обратите внимание, как член класса name при помощи self
отделен от аргумента конструктора name
. Аргументы передаются в конструктор обычным образом, как и в любой другой метод класса. Обратите внимание на то, что каждый член класса должен быть проинициализирован – либо при объявлении (как, например, numberOfSides
), либо в конструкторе (как name
).
Деструктор класса – метод deinit
, который можно переписать в случае необходимости.
Чтобы наследовать класс от уже существующего класса, после указания имени дочернего класса следует поставить двоеточие и указать название родительского. В Swift нет никаких ограничений по обязательному наследованию какого-либо стандартного класса.
Переопределенные дочерним классом методы должны быть помечены ключевым словом override
– переопределение методов без override приведет к ошибке. Компилятор также выявляет методы, маркированные override
, но не переопределяющие какие-либо методы своего родительского класса.
class Square: NamedShape {
var sideLength: Double
init(sideLength: Double, name: String) {
self.sideLength = sideLength
super.init(name: name)
numberOfSides = 4
}
func area() -> Double {
return sideLength * sideLength
}
override func simpleDescription() -> String {
return "A square with sides of length (sideLength)."
}
}
let test = Square(sideLength: 5.2, name: "my test square")
test.area()
test.simpleDescription()
Давайте поэкспериментируем
Создайте классCircle
и наследуйте его от классаNamedShape
. Конструктор классаCircle
принимает два аргумента – радиус и название. Переопределите методыarea
иdescribe
этого класса.
Члены класса могут также иметь собственные getter
и setter
.
class EquilateralTriangle: NamedShape {
var sideLength: Double = 0.0
init(sideLength: Double, name: String) {
self.sideLength = sideLength
super.init(name: name)
numberOfSides = 3
}
var perimeter: Double {
get {
return 3.0 * sideLength
}
set {
sideLength = newValue / 3.0
}
}
override func simpleDescription() -> String {
return "An equilateral triagle with sides of length (sideLength)."
}
}
var triangle = EquilateralTriangle(sideLength: 3.1, name: "a triangle")
triangle.perimeter
triangle.perimeter = 9.9
triangle.sideLength
В setter
-е переменной perimeter
новое присваиваемое значение неявно называется newValue
. Вы можете изменить название этой переменной, указав его в скобках сразу после set
.
Обратите внимание на структуру конструктора класса EquilateralTriangle
. Этот метод включает в себя три последовательных шага:
- инициализация членов дочернего класса;
- вызов конструктора родительского класса;
- изменение значений членов родительского класса.
Если вам необходимо выполнить определенный код до или после присваивания нового значения переменной, вы можете переопределить методы willSet
и didSet
нужным вам образом. Например, в приведенном ниже классе гарантируется, что длина стороны треугольника всегда будет равна длине стороны квадрата.
class TriangleAndSquare {
var triangle: EquilateralTriangle {
willSet {
square.sideLength = newValue.sideLength
}
}
var square: Square {
willSet {
triangle.sideLength = newValue.sideLength
}
}
init(size: Double, name: String) {
square = Square(sideLength: size, name: name)
triangle = EquilateralTriangle(sideLength: size, name: name)
}
}
var triangleAndSquare = TriangleAndSquare(size: 10, name: "another test shape")
triangleAndSquare.square.sideLength
triangleAndSquare.triangle.sideLength
triangleAndSquare.square = Square(sideLength: 50, name: "larger square")
triangleAndSquare.triangle.sideLength
У методов классов имеется одно важное отличие от функций. Названия аргументов функции используются только в пределах этой функции, тогда как в методе класса параметры также используются при вызове этого метода (кроме первого параметра). По умолчанию метод класса имеет одинаковые названия параметров как при вызове, так и внутри себя. Однако вы можете указать другое название (в примере ниже – times
), которое будет использовано только внутри этого метода. При этом для вызова этого метода необходимо использовать первое название (numberOfTimes
).
class Counter {
var count: Int = 0
func incrementBy(amount: Int, numberOfTimes times: Int) {
count += amount * times
}
}
var counter = Counter()
counter.incrementBy(2, numberOfTimes: 7)
При работе с опциональными значениями добавьте знак вопроса (?
) перед методами, членами класса и т.д. Если значение перед знаком вопроса равно nil
, все, что следует после (?
) игнорируется и значение всего выражения равно nil
. В противном случае выражение вычисляется обычным образом. В обоих случаях результатом всего выражения будет опциональное значение.
let optionalSquare: Square? = Square(sideLength: 2.5, name: "optional square")
let sideLength = optionalSquare?.sideLength
Перечисления и Структуры
Для создания перечислений используется ключевое слово enum
. Отметим, что перечисления также могут иметь в своем составе методы.
enum Rank: Int {
case Ace = 1
case Two, Three, Four, Five, Six, Seven, Eight, Nine, Ten
case Jack, Queen, King
func simpleDescription() -> String {
switch self {
case .Ace:
return "ace"
case .Jack:
return "jack"
case .Queen:
return "queen"
case .King:
return "king"
default:
return String(self.toRaw())
}
}
}
let ace = Rank.Ace
let aceRawValue = ace.toRaw()
Давайте поэкспериментируем
Напишите функцию, которая сравнивает 2 перечисления типаRank
по их значениям.
В вышеприведенном примере элементы перечисления первоначально имеют целочисленный тип, и вам достаточно указать значение только первого элемента – значения остальных элементов будут определены в соответствии с порядком их следования. В качестве исходного типа (raw value) значений элементов вы также можете выбрать строковый или вещественные типы.
Для преобразования исходного типа значения в тип перечисления используйте функции toRaw
и fromRaw
.
if let convertedRank = Rank.fromRaw(3) {
let threeDescription = convertedRank.simpleDescription()
}
Отметим, что значения элементов перечисления являются фактическими, а не просто иной записью своих исходных значений. Вообще говоря, вы можете и не указывать их исходные значения.
enum Suit {
case Spades, Hearts, Diamonds, Clubs
func simpleDescription() -> String {
switch self {
case .Spades:
return "spades"
case .Hearts:
return "hearts"
case .Diamonds:
return "diamonds"
case .Clubs:
return "clubs"
}
}
}
let hearts = Suit.Hearts
let heartsDescription = hearts.simpleDescription()
Давайте поэкспериментируем
Добавьте методColor
, возвращающий строку“black”
дляSpades
иClubs
и“red”
дляHearts
иDiamonds
.
Обратите внимание на то, как осуществляется доступ к члену Hearts
перечисления Suit
. При присваивании значения константе hearts
используется полное имя Suit.Hearts
, поскольку мы явно не указываем тип этой константы. А в switch
мы используем сокращенную форму .Hearts
, поскольку тип значения self
априори известен. Вы можете использовать сокращенную форму повсеместно, если тип переменной явно указан.
Для создания структур используется ключевое слово struct
. Структуры имеют множество схожих черт с классами, включая методы и конструкторы. Одним из наиболее существенных отличий структур от классов является то, что экземпляры структур, в отличие от экземпляров классов, передаются в функции по значению (то есть предварительно создается их локальная копия), тогда как экземпляры классов передаются по ссылке.
struct Card {
var rank: Rank
var suit: Suit
func simpleDescription() -> String {
return "The (rank.simpleDescription()) of (suit.simpleDescription())"
}
}
let threeOfSpades = Card(rank: .Three, suit: .Spades)
let threeOfSpadesDescription = threeOfSpades.simpleDescription()
Давайте поэкспериментируем
Добавьте в структуру Card метод, который создает полную колоду карт.
Экземпляр члена перечисления может иметь собственные значения и они могут быть разными. Вы присваиваете эти значения при создании экземпляра перечисления (константа success
в примере). Связанные и исходные значения это разные вещи: исходное значение члена перечисления всегда постоянно для всех экземпляров перечисления и указывается при его объявлении.
Рассмотрим пример получения с сервера времени восхода и заката Солнца. Сервер отправляет в ответ либо соответствующую информацию, либо сообщение об ошибке.
enum ServerResponse {
case Result(String, String)
case Error(String)
}
let success = ServerResponse.Result("6:00 am", "8:09 pm")
let failure = ServerResponse.Error("Out of cheese.")
switch success {
case let .Result(sunrise, sunset):
let serverResponse = "Sunrise is at (sunrise) and sunset is at (sunset)."
case let .Error(error):
let serverResponse = "Failure... (error)"
}
Давайте поэкспериментируем
Добавьте третий вариант в оператор множественного выбораswitch
Обратите внимание, каким образом из объекта ServerResponse
“вытаскиваются” время восхода и заката.
Протоколы и Расширения.
Для объявления протокола используйте ключевое слово protocol
.
protocol ExampleProtocol {
var simpleDescription: String { get }
mutating func adjust()
}
Протоколы могут поддерживаться классами, перечислениями и структурами.
class SimpleClass: ExampleProtocol {
var simpleDescription: String = "A very simple class."
var anotherProperty: Int = 69105
func adjust() {
simpleDescription += " Now 100% adjusted."
}
}
var a = SimpleClass()
a.adjust()
let aDescription = a.simpleDescription
struct SimpleStructure: ExampleProtocol {
var simpleDescription: String = "A simple structure"
mutating func adjust() {
simpleDescription += " (adjusted)"
}
}
var b = SimpleStructure()
b.adjust()
let bDescription = b.simpleDescription
Давайте поэкспериментируем
Создайте перечисление, которое будет реализовывать этот протокол.
Обратите внимание на ключевое слово mutating
в определении структуры SimpleStructure
, которое информирует компилятор о том, что соответствующий метод подвергает структуру изменениям. В противовес этому методы класса SimpleClass
не нужно маркировать как mutating
, поскольку методы класса всегда могут беспрепятственно его изменять.
Для добавления новых методов или членов класса в уже существующий тип необходимо использовать расширения – extensions
. Вы также можете использовать расширения для реализации протокола уже существующим типом, даже если он импортирован из какой-либо библиотеки или фреймворка.
extension Int: ExampleProtocol {
var simpleDescription: String {
return "The number (self)"
}
mutating func adjust() {
self += 42
}
}
7.simpleDescription
Давайте поэкспериментируем
Создайте расширение типаDouble
с переменной-членомabsoluteValue
.
Вы можете использовать название протокола как и любой другой тип – например, чтобы создать массив объектов разного типа, но реализующих общий протокол. Заметьте, что при работе с объектами такого типа методы, объявленные вне протокола, будут недоступны.
let protocolValue: ExampleProtocol = a
protocolValue.simpleDescription
// protocolValue.anotherProperty // Uncomment to see the error
Несмотря на то, что во время выполнения программы переменная protocolValue
имеет тип SimpleClass
, компилятор считает, что ее тип – ExampleProtocol
. Это означает, что вы не сможете случайно получить доступ к методам или членам класса, которые реализуются вне протокола ExampleProtocol
.
Обобщенные типы (generics)
Для создания обобщенного типа, заключите имя в угловые скобки (<>
).
func repeat<ItemType>(item: ItemType, times: Int) -> ItemType[] {
var result = ItemType[]()
for i in 0..times {
result += item
}
return result
}
repeat("knock", 4)
Создавайте обобщенные функции, классы, перечисления и структуры.
// Reimplement the Swift standard library's optional type
enum OptionalValue<T> {
case None
case Some(T)
}
var possibleInteger: OptionalValue<Int> = .None
possibleInteger = .Some(100)
Если вы хотите задать обобщенные типу определенные требования, такие, как, например, реализация протокола или требование быть наследованным от определенного класса, используйте where
.
func anyCommonElements <T, U where T: Sequence, U: Sequence, T.GeneratorType.Element: Equatable, T.GeneratorType.Element == U.GeneratorType.Element> (lhs: T, rhs: U) -> Bool {
for lhsItem in lhs {
for rhsItem in rhs {
if lhsItem == rhsItem {
return true
}
}
}
return false
}
anyCommonElements([1, 2, 3], [3])
Давайте поэкспериментируем
Измените функциюanyCommonElements
таким образом, чтобы она возвращала массив общих элементов.
В простых случаях вы можете опустить where
и написать имя протокола или класса после двоеточия. Выражение <T: Equatable>
эквивалентно выражению <T where T: Equatable>
.
Хотите внедрить подписки в iOS-приложение за 10 минут? Интегрируйте Apphud и:
— оформляйте покупки с помощью лишь одного метода;
— автоматически отслеживайте состояние подписки каждого пользователя;
— легко интегрируйте Subscription Offers;
— отправляйте события о подписках в Amplitude, Mixpanel, Slack и Telegram с учетом локальной валюты пользователя;
— уменьшайте Churn rate в приложениях и возвращайте отписавшихся пользователей.
Эта статья будет полезна как новичкам, так и опытным программистам. Если вы новичок, то Swift отлично подходит на роль первого ЯП, а если вы гуру, то никогда не бывает лишним закрепить свои знания. Здесь каждый найдет для себя, что-то полезное.
Хотя этот туториал и не займет много времени, в нем вы познакомитесь со всем самым необходимым: переменными, управлением потока, классами, лучшими практиками и многим другим. Также, в конце обучения, мы попробуем написать наше первое (а для кого-то нет) приложение.
Для того чтобы благополучно пройти этот туториал, вам понадобится версия Xcode не ниже 6.1.1 (версия Xcode на время написания статьи).
Привет, Playground!
При запуске Xcode 6 мы увидим вот что:
Нажимаем на Get started with playground, даем свое имя и жмем Далее (вариант выбора платформы на данном этапе нас не интересует). Сохраняем наш playground в удобном для вас месте и приступаем.
Мы создали новый тип Playground файла, который позволяет нам тестировать Swift-код и моментально видеть результат. К примеру, попробуйте добавить следующие строчки кода в ваш Playground:
let tutorialTeam = 60
let editorialTeam = 17
let totalTeam = tutorialTeam + editorialTeam
Спорим, что как только вы написали эти три строчки, вы сразу увидели результат работы в правой части? Это очень удобно, не так ли?
Playground — лучший инструмент для изучения языка. Вы можете экспериментировать с кодом, работать с новыми API (наборами классами и процедур), отрабатывать свои алгоритмы или визуализировать ваши идеи. До конца этого туториала мы будем работать в этой «игровой площадке».
Заметка
Перенесите файл SwiftPlaygorund.playground на панель быстрого запуска. Таким образом, вы всегда сможете быстро его открыть для тестирования вашего кода на Swift.
Переменные и константы в Swift
Попробуйте добавить следующую строку в конец вашего кода в Playground:
totalTeam += 1
Вы сразу можете обратить внимание на ошибку, все дело в том, что totalItem — константа, а это означает, что ее значение не может быть изменено. Мы объявляем константы с помощью ключевого слова let. Если вы хотите, чтобы значение totalItem менялось, то можно объявить его с помощью ключевого слова обозначения переменной var, вместо let. Изменив нашу строку, получаем результат:
var totalTeam = tutorialTeam + editorialTeam
Сейчас наш код исполняется без ошибок! Вы наверное думаете: «А почему бы всегда не использовать var вместо let, раз он менее строгий?» Все дело в том, что Swift — язык строгой типизации, и в Apple нам советуют применять var только в тех случаях, когда это действительно необходимо. Подобные правила помогают в оптимизации кода при компиляции приложения.
Явная и неявная типизация
Таким образом мы не указываем явно типы для этих констант и переменных, потому что компилятор имеет достаточно информации для того, чтобы эти типы вывести автоматически.
К примеру, мы указали значение для tutorialTeam равное 56, таким образом компилятор знает, что 56 принадлежит к типу Int, поэтому и tutorialTeam, так же будет принадлежать к Int.
Вообще, вы можете указать тип явно, если хотите. Попробуйте заменить строку объявления tutorialTeam на следующую:
let tutorialTeam: Int = 60
Вы можете задаться вопросом: «Как же все-таки лучше делать: указывать тип явно или позволить компилятору его вывести самостоятельно?» — лучшей практикой считается, позволить Swift вывести тип автоматически. Это сделает ваш код более коротким и читабельным, что соответствует философии нового языка от Apple и благоприятно скажется на оптимизации вашего кода.
Мы выяснили, что в данном случае лучшей практикой для нас будет указывать тип переменной лишь при необходимости, поэтому, удаляем Int:
let tutorialTeam = 60
Базовые типы и управление потоком в Swift
Только что вы познакомились с типом Int, который является типом для обозначения целочисленных значений, но есть еще несколько других типов.
Float и Double
Давайте попробуем вставить еще пару строк в конец нашей игровой площадки и познакомимся с базовыми типами Float и Double:
let priceInferred = 19.99
let priceExplicit: Double = 19.99
Есть два типа для работы с числами с плавающей точкой: Float и Double:
- Double — представляет собой 64-битное число с плавающей точкой. Используйте его когда число с плавающей точкой должно быть очень большим или чрезвычайно точным
- Float — представляет собой 32-битное число с плавающей точкой. Используйте его, когда значение не нуждается в 64-битной точности.
Тип Double — более точный, чем Float и является типом по умолчанию. Это значит, что константа priceInferred, является так же типом Double. Поэтому, если мы хотим заменить тип Double на тип Float, мы должны написать следующее:
let priceInferred: Float = 19.99
let priceExplicit = 19.99
//мы не указываем тип Double во второй строке, потому что Swift выводит его автоматически
Bool
Вписываем себе пример констант логического типа Bool:
let onSaleInferred = true
let onSaleExplicit: Bool = false
Обратите внимание, что логические значения в Swift имеют значения true или false, в отличии от YES/NO в Objective-C. Так же как с Int и Double, вам не нужно указывать константы или переменные как Bool, если при создании вы присвоили им значения true или false.
String
Подобрались к строковым значениям:
let nameInferred = "Whoopie Cushion"
let nameExplicit: String = "Whoopie Cushion"
Обратите внимание, что больше мы не используем символ @ как в Objective-C.
Конструкции If и интерполяция строк
if onSaleInferred {
print("(nameInferred) on sale for (priceInferred)!")
} else {
print("(nameInferred) at regular price: (priceInferred)!")
}
Условное выражение выглядит очень похоже на любой другой язык. Круглые скобки вокруг условия опциональны, а вот фигурные скобки обязательны даже в тех случаях, когда вам нужно исполнить всего одну строку кода!
Так, в примере выше есть новая техника, называемая интерполяция строк. Если вы захотите вставить что-то в строку, что может быть заменено по значению, то вы должны использовать вот такой простой синтаксис: «(ваше выражение)».
Вы можете наблюдать работу функции print() в боковой панели, но это может быть проблематично, если ваша строка длинная. Для того, чтобы увидеть результат полностью вам нужно нажать на пиктограмму глаза, в правой части playground’а, который появится при наведении на строку результата:
Есть и другой способ посмотреть длинное значение выражения. Вам нужно пройти в главное меню Xcode (то, что наверху) ViewAssistant EditorShow Assistant Editor.
Assistant Editor покажет вам результат работы функции print() без наведения на строку результата, что согласитесь, само по себе проще. Если вы что-то не поняли, то можете скачать наш файл playground’а со всем кодом что был написан выше.
Классы и Методы
Одна из самых частых вещей, которую вы будете делать при разработке приложении на Swift — создание классов и методов. Удалите все, что написали ранее в файл нашего playground’а.
Далее, мы создадим класс, который поможет нам, допустим, посчитать количество чаевых, которые мы должны оставить в ресторане.
// 1
class TipCalculator {
}
Для того чтобы создать класс, нужно поставить ключевое слово class, после которого написать его имя. После чего, нужно написать фигурные скобки для тела класса.
Если вы создаете субкласс, то после имени субкласса, вам нужно поставить двоеточие и имя суперкласса. В отличии от Objective-C в Swift вам не нужно постоянно писать суперкласс NSObject или что-то другое. Добавьте в фигурные скобки следующее:
// 2
let total: Double
let taxPct: Double
let subtotal: Double
После того, как вы добавите этот код, вы получите несколько ошибок, не переживайте, мы скоро их исправим.
Свойства класса создаются точно так же как и просто константы или переменные. Здесь мы создали три константных свойства: первое — счет после уплаты налогов, второе — налоги, третье — счет до уплаты налогов.
Обратите внимание, что вы обязаны указывать начальное значение для свойств при их объявлении, также, вы можете указать их в инициализаторе. Но мы не сделали ни того, ни другого, поэтому получаем ошибки. Если нет желания указывать начальное или исходное значение, то необходимо объявить свойства как опционалы, но это совсем другая история, то есть туториал.
Теперь добавьте следующий блок в фигурные скобки:
// 3
init(total: Double, taxPct: Double) {
self.total = total
self.taxPct = taxPct
subtotal = total / (taxPct + 1)
}
Тут мы создали инициализатор для класса, который принимает два параметра. Инициализатор всегда называется ключевым словом init в Swift. Вы можете создать несколько инициализаторов, если вам так угодно, вот только они должны принимать разные параметры.
Смотрите, мы дали параметрам этого метода такие же имена как и свойствам класса. И, чтобы их не путать, мы поставили ключевое слово self.
Теперь, у нас нет никакого конфликта имен для свойства subtotal, так что нам больше не нужно добавлять self, потому что компилятор уже автоматически выводит его, когда это нужно. Для тех, кому не все равно откуда взялось subtotal = total / (taxPct + 1) поясним:
(subtotal * taxPct) + subtotal = total
subtotal * (taxPct + 1) = total
subtotal = total / (taxPct + 1)
Теперь, добавьте следующий блок кода в фигурные скобки (после предыдущего в фигурных скобках):
// 4
func calcTipWithTipPct(tipPct: Double) -> Double {
return subtotal * tipPct
}
Поясним, что для написания метода нам пригодится ключевое слово func. Когда мы создаем метод, мы должны указывать тип параметров явно и выходной тип метода, после результирующей стрелки ->.
Эта функция определяет размер налога, путем перемножения процента на общую сумму.
Теперь, добавляем следующий блок и снова в самый конец фигурных скобок:
// 5
func printPossibleTips() {
print("15%: (calcTipWithTipPct(0.15))")
print("18%: (calcTipWithTipPct(0.18))")
print("20%: (calcTipWithTipPct(0.20))")
}
Вот этот блок, когда представляет из себя новый метод, который выводит на экран три возможных варианта чаевых. Когда вы вызываете метод класса, то первый параметр необязательно должен иметь имя, но остальные должны.
Также, обратите внимание, что интерполяция строки не имеет ограничения в выводе переменных. Вы можете вписывать туда все что угодно — любые операции, которые только придут вам в голову!
Теперь, давайте добавим последний кусок кода в самый конец, после фигурных скобок:
// 6
let tipCalc = TipCalculator(total: 33.25, taxPct: 0.06)
tipCalc.printPossibleTips()
Наконец-то, мы создали подобие калькулятора для чаевых Вот, что в итоге у нас должно было получиться в нашей «игровой площадке»:
// 1
class TipCalculator {
// 2
let total: Double
let taxPct: Double
let subtotal: Double
// 3
init(total: Double, taxPct: Double) {
self.total = total
self.taxPct = taxPct
subtotal = total / (taxPct + 1)
}
// 4
func calcTipWithTipPct(tipPct: Double) -> Double {
return subtotal * tipPct
}
// 5
func printPossibleTips() {
print("15%: (calcTipWithTipPct(0.15))")
print("18%: (calcTipWithTipPct(0.18))")
print("20%: (calcTipWithTipPct(0.20))")
}
}
// 6
let tipCalc = TipCalculator(total: 33.25, taxPct: 0.06)
tipCalc.printPossibleTips()
Проверьте ваш Assistant Editor на наличие результата:
Массивы и цикл For
В данный момент у нас есть некоторое дублирование кода, потому что мы вызываем метод calcTipWithTipPct несколько раз, с различным процентом чаевых. Вы можете уменьшить дублирование кода, используя массив.
Замените содержимое printPossibleTips вот это:
let possibleTipsInferred = [0.15, 0.18, 0.20]
let possibleTipsExplicit:[Double] = [0.15, 0.18, 0.20]
Мы создали массивы с явным указанием типа и без него (просто для демонстрации). Не забывайте, что синтаксис [Double] является сокращенным вариантом Array<Double>.
Теперь, добавим эти строки ниже:
for possibleTip in possibleTipsInferred {
print("(possibleTip*100)%: (calcTipWithTipPct(possibleTip))")
}
Вы можете написать альтернативный вариант вот в такой форме:
for i in 0..<possibleTipsInferred.count {
let possibleTip = possibleTipsInferred[i]
print("(possibleTip*100)%: (calcTipWithTipPct(possibleTip))")
}
Оператор ..< является полузакрытым оператором диапазона и не включает в себя верхнюю границу. Есть также оператор … который является закрытым.
Массивы имеют свойство count, для подсчета количества своих элементов. Вы так же можете обратиться к конкретному элементу, используя синтаксис arrayName[index], который мы использовали здесь.
Словари
Давайте сделаем еще одно небольшое изменение в нашем чудо-калькуляторе чаевых. Вместо того, чтобы просто выводить значение чаевых, мы вернем словарь значений. Такой подход позволит упростить отображение результатов в некоторых интерфейсах.
Удаляем метод printPossibleTips и вместо него пишем:
// 1
func returnPossibleTips() -> [Int: Double] {
let possibleTipsInferred = [0.15, 0.18, 0.20]
let possibleTipsExplicit:[Double] = [0.15, 0.18, 0.20]
// 2
var retval = [Int: Double]()
for possibleTip in possibleTipsInferred {
let intPct = Int(possibleTip*100)
// 3
retval[intPct] = calcTipWithTipPct(possibleTip)
}
return retval
}
Вылезла ошибка, но не бойтесь, она поправима. Начнем сверху нашего кода и пройдемся от секции к секции:
- Объявляем метод, который возвращает словарь, где ключ типа Int (процент чаевых), значение типа Double (посчитанные чаевые). И не забывайте, что [Int: Double] — сокращенный вариант Dictionary<Int, Double>.
- Тут мы создаем пустой словарь. Обратите внимание на то, что мы собираемся его изменять, а значит, мы должны объявить через ключевое слово var, но не let. Если мы объявим через let, то при попытки изменить его мы получим ошибку компиляции.
- Здесь присваиваем значение элементу словаря по ключу.
Наконец, осталось изменить последнюю строку нашей игровой площадки. Собственно, именно она и исправит ошибку.
tipCalc.returnPossibleTips()
После того как произойдут некоторые вычисления, вы увидите в инспекторе результат в виде словаря (нажмите на глаз для расширенного вида):
Примите наши поздравления! Вы сделали свой первый калькулятор чаевых на Swift! Конечный вариант нашего playground.
Что делать дальше? Продолжайте читать туториалы и перевод книги по Swift. Надеемся, данная статья была для вас полезной. До встречи в следующем уроке!
Данный урок подготовлен для вас командой: SwiftBook.ru
Урок подготовил: Иван Акулов
Источник урока: http://www.raywenderlich.com/74438/swift-tutorial-a-quick-start
Итак, продолжим знакомство с простым и интересным языком Swift. В прошлый раз мы познали базовые команды и функции перспективного языка программирования. А теперь сделаем своё первое приложение!
Как создать приложение для iOS
Сегодня мы сделаем простое приложение для расчета индекса массы тела и необходимого количества калорий для поддержания веса. Для этого будем использовать формулы Гарисса Бенедикта и индекса массы тела.
1. Для начала давайте создадим проект: запустите Xcode и нажмите комбинацию клавиш CMD+Shift+N или выберите в меню File->New->Project
2. Теперь выберите Tabbed Application и нажмите Next.
3. На этом этапе надо придумать имя для приложения (Product Name), нажать Next и выбрать папку для сохранения. Параметры Organization Name и Organization Identifier можете не менять.
Главное, чтобы значение в поле Language было равно Swift.
4. После того, как вы сохраните проект, перед вами появится рабочее пространство Xcode.
Слева у вас будет панель Navigator, а справа — Utilities. В каждой из этих панелей есть свои вкладки, которые позволяют получить доступ к различным функциям.
Например, первая влкадка в панеле Navigator показывает список файлов проекта, третья позволяет производить поиск по проекту и так далее.
5. Найдите в списке файлов проектов файл с именем Main.storyboard и нажмите на него.
Файл Main.storyboad определяет, какие экраны (контроллеры) есть в приложении. Вы можете добавлять элементы на экраны, задавать связи между экранами и так далее.
Если вы выберите какой-нибудь контроллер, он подсветится синей рамкой:
После того, как контроллер выбран, его свойства начнут отображаться в панели Utilities. Например, контроллеру можно поменять размер, выбрав другое значение в поле Size.
6. Запустим наше шаблонное приложение и посмотрим, как оно выглядит в симуляторе. Для этого надо в верхнем левом углу выбрать тип симулируемого устройства и нажать комбинацию клавиш CMD+R или кнопку с икокой Play.
Как видите, у нас есть приложение с двумя экранами, преключение между которым осуществляется при помощи таб-бара.

7. Нужно переименовать название табов. Для того, чтобы это сделать, надо выбрать таб, кликнув на него или выбрав его в иерархии элементов управления.
После того как таб будет выбран, он подсветится зеленым цветом.
8. Теперь в панели Utilities выбирайте Attributes Inspector и меняйте значение в поле Title на BMR/BMI для первого таба и Килокалории для второго.
Сейчас на первом контролере размещены всякие надписи. Их надо удалить. Для этого выделите их и нажмите Delete.
9. Теперь добавим свои элементы управления. Внизу панели Utilities есть Object Library, в которой можно выбрать объекты и добавить их к сцене. Найдите объект Label и перетащите его на контроллер BMR/BMI. Перед этим не забудьте два раза тапнуть на сцене, чтобы масштаб стал стандартным.
Должно получиться примерно так.
В панели Utilities можно поменять текст, размер шрифта и так далее.
10. Перетащите еще несколько лейблов и поставьте им такой же текст, как и на картинке. Для последнего лейбла нужно поставить Lines в 2, чтобы текст переносился на другую строку.
11. Теперь добавьте 3 текстовых поля (Text Field).
И разместите их, как на картинке.
У текстовых полей поставьте параметр keyboard type в Number Pad.
И установите текст по умолчанию.
12. Теперь добавим элементы управления для выбора пола и кол-ва тренировок в неделю. В Object Library ищете Segmented Control и добавляйте на экран.
У Segmented Control можно менять количество сегментов и текст для каждого сегмента.
Сделайте так, чтобы сегменты выглядели, как на скриншоте.
13. Теперь добавьте кнопку (button).
И установите ей заголовок.

После этого добавьте еще один label с lines равным 4.
14. Выберите контроллер BMI/BMR, нажмите два пересекающихся кольца в правом верхнем углу и откроется Assistant Editor. Он показывает код, ассоцированный с этим контроллером.
15. Протащим элементы управления.
Для этого выберите первый text field (в нашем случае это будет возраст), нажмите Ctrl, кликните на него еще раз и, не отпуская кнопки, перетащите внутрь класса. Если все сделано правильно, то вы увидите посказку “Insert Outlet, Action, …”.
Теперь отпустите курсор, и вы увидете окошко для создания связи. В качестве имени введите ageTextField и нажмите Connect.
16. У вас появится переменная ageTextField.
Проделайте эту процедуру для оставшихся text field, segmented controls и label с текстовым результатом. У вас должно получиться так:
Теперь протащите кнопку, но тип соединения укажите не Outlet, а Action. И в качестве имени используйте calculateTapped.
17. Теперь скопируйте следующий код в метод calculateTapped.
Этот код выполняет расчет и выводит результат на экран.
18. Пришло время подвести итог. Давайте запустим и проверим:
Ваша первая программа готова! Молодцы!
Задавайте вопросы
Если что-то не получается по ходу дела, пишите в комментарии. Специально для этого мы пронумеровали каждый пункт. На все вопросы ответят разработчики-профессионалы из команды, так что не стесняйтесь.
Над текстом трудился Руслан Гуменный — ведущий разработчик e-Legion. Компания является лидером на рынке заказной мобильной разработки в Европе, входит в состав холдинга DZ Systems. За 9 лет существования были созданы приложения для РайффайзенБанка, Яндекса, BMW, Банка Москвы, Первого Канала, Aviasales, Sports.ru, ВГТРК, Mail.Ru Group и многих других компаний.
Если вы шарите в теме и вам есть, что добавить, не стесняйтесь – пишите в редакцию со своими статьями на тему разработки приложений. В следующем выпуске подробнее рассмотрим, что было сделано и доработаем приложение, подготовив его к публикации. Так что подготовьтесь заранее, сделав домашнее задание
Уверен, все остальные давно мечтали «сделать свое приложение для айфона». Это ваш шанс. До скорых встреч в следующих статьях цикла!
(6 голосов, общий рейтинг: 4.67 из 5)
🤓 Хочешь больше? Подпишись на наш Telegram.
iPhones.ru
Итак, продолжим знакомство с простым и интересным языком Swift. В прошлый раз мы познали базовые команды и функции перспективного языка программирования. А теперь сделаем своё первое приложение! Как создать приложение для iOS Сегодня мы сделаем простое приложение для расчета индекса массы тела и необходимого количества калорий для поддержания веса. Для этого будем использовать формулы Гарисса…
- e-legion,
- инструкции,
- Это интересно
Swift — лучший язык программирования, который вы должны выучить, чтобы легко создать приложение своей мечты. Swift — это мощный, но простой в освоении язык программирования, созданный Apple. Он часто используется для разработки приложений для iOS и macOS, а также приложений для tvOS и watchOS. Хотя вы можете использовать и другие языки для создания приложений Apple, Swift является предпочтительным и рекомендованным языком, потому что его код безопасен для дизайна и позволяет создавать молниеносно быстрое программное обеспечение. Swift создан, чтобы помочь разработчикам писать в увлекательной и интерактивной форме, с более удобным для чтения синтаксисом, безопасностью, предотвращающей ошибки программирования, и современными функциями, повышающими устойчивость к сбоям.
Что такое Swift-программирование?
Swift потребовались годы, чтобы разработать и улучшить существующие функции языка C; он улучшает компилятор, отладчик и инфраструктуру фреймворка. Он предоставляет доступ к текущему фреймворку Cocoa, в комбинации с Objective C. Swift предлагает множество новых функций и объединяет объектно-ориентированную и процедурную части языка. Основная цель swift — стать лучшим языком для использования мобильных приложений, десктопов, системного программирования и облачных сервисов. Программирование на языке Swift было разработано для облегчения исправления ошибок разработчиком.
Особенности Swift
Некоторые замечательные функции Swift делают его лучше предыдущих версий языков программирования. Swift улучшает их время от времени, что делает его более эффективным и обновляющимся языком программирования.
Безопасность
В целях безопасности, важно указать на ошибки разработчика iOS, прежде чем программное обеспечение будет запущено в производство. Swift не позволяет передавать неточные данные или переменную через программу, пока они не будут в правильной форме. Пользователю, может показаться сложным, прохождение мер безопасности, но это сэкономит много времени в будущем. Также это экономит память, так как Swift не принимает небезопасный код; в следствии чего не будет кеша засоряющего память.
Быстрота
Swift был создан как замена языкам на основе C; его производительность аналогична языку C в большинстве задач. Но он работает со всеми функциями и системами iOS быстро. Он имеет технологию компилятора LLVM, которая делает написание кода быстрым и эффективным. Производительность кода ускоряет работу гаджетов, например: ТВ-приложений, часов или мобильных приложений.
Выразительность
Swift предлагает простой и интуитивно понятный синтаксис, который нужен именно разработчикам iOS. Разработчики могут легко писать более выразительные коды, используя синтаксис Swift. Swift был разработан с такими функциями Objective-C, как дженерик и null, которые делают код Swift чище, а безопасно программировать становится проще.
Открытый исходный код
Swift создается на сайте swift.org, открытой структуре с исходным кодом, системой отслеживания ошибок, списком рассылки и обычным списком разработчиков. Об этом заботится группа разработчиков, которые работают с сообществом над улучшением и постоянным обновлением языка. Swift поддерживает все платформы Apple; это делает программирование простым, быстрым и безопасным. Учитывая высокий спрос на Swift, разработчики усердно работают над запуском его на других платформах.
Почему я должен начать изучать Swift?
Прежде чем вы начнете программировать на Swift, важно знать, почему вы должны его изучать. Язык программирования Swift разработан таким образом, чтобы его было легко освоить и использовать. Apple разработал этот язык с новым написанием кода. Независимо от того, являетесь ли вы студентом, ищете новую карьеру или хотите научиться программировать, Swift — это первый язык программирования, который прост и интуитивно понятен в изучении. Если вы новичок в программировании, приложение Swift для iPad (Playgrounds) упрощает изучение Swift. Я перечислил некоторые сферы применения Swift, изучив которые, вы сможете зарабатывать:
- Разработка мобильных приложений
- Программирование базы данных
- Разработка 3D систем
- Программная инженерия
- Проектирование библиотек
- Машинное обучение
- Аудио инженерия
- Тестировщики программного обеспечения
Плюсы и минусы языка Swift
Давайте прольем свет на плюсы и минусы языка Swift, чтобы решить, стоит ли вам его изучать.
Плюсы | Минусы |
Легко учить Code Swift прост в освоении и использовании, и у него есть доступ к обучению созданию курсов по приложениям Xcode. |
Слабая кроссплатформенная поддержка Code Swift поддерживает все платформы Apple; он лучше всего подходит для нативной разработки iOS. |
Современный Code Swift легко читать и поддерживать, он понятен и не содержит ошибок. |
Частые обновления Попробуйте no-code платформу AppMaster AppMaster поможет создать любое веб, мобильное или серверное приложение в 10 раз быстрее и 3 раза дешевле Начать бесплатно Swift — это новейший язык, который часто обновляется. Поиск правильных инструментов для решения определенных задач может быть трудным. |
Большое сообщество У Swift есть сообщества с открытым исходным кодом, а также множество ресурсов, которые помогут вам в изучении языка. |
|
Кроссплатформенность Swift поддерживает все платформы Apple, Windows, Linux и Ubuntu. |
|
Стремительное будущее Swift со временем набирает популярность и привлекает больше внимания поклонников, чем другие языки программирования. |
Как видим, плюсов гораздо больше, чем минусов, и все эти минусы, похоже, исчезнут в ближайшем будущем. После того, как вы изучите программирование Swift, вы станете успешным кандидатом для потенциальных работодателей. Разработчики Code Swift пользуются большим спросом и получают хорошую зарплату для разработчика iOS в США. После изучения программирования Swift у вас будут большие возможности. Некоторые известные компании используют код Swift для своей разработки, например Apple, Linkedin, Uber, Whatsapp, Slack, Facebook, Accenture, Microsoft и Firefox.
Как начать изучать программирование на Swift?
Если вы хотите начать учить Swift, вы можете сделать это онлайн, на официальном сайте. На этом веб-сайте есть соответствующие файлы и рекомендации по этому языку. Кроме того, по мере роста популярности языка, большое количество данных становятся доступными в различных блогах, а также на Youtube. Начните изучение Swift с официального сайта, а затем следуйте своему пути в соответствии со своим опытом.
Swift — это будущее языков программирования; он преодолевает язык C, Python и многие другие языки программирования, которые требуют написания кода. Много ли способов научиться программированию на Swift? И ответ — да, безусловно много! Вот некоторые из примеров:
- Официальный сайт Apple
- Бесплатные онлайн-курсы
- Платные онлайн-курсы
- YouTube видео
- Учебники
- Сообщения в блоге
- Подкасты
- Книги
- Документация
Совет: Если вы новичок, вам следует смотреть обучающие видеоролики, потому что вы сможете лучше понять тему, посмотрев, а затем повторив это самостоятельно.
Легко ли изучить Swift для начинающих?
Да, изучить основы для запуска языка программирования Swift несложно, но нелегко понять расширенные функции разработки iOS по мере продвижения вперед. Но не теряйте надежды; вы можете создать свое первое простое приложение без расширенных функций. Как только вы закончите свой первый проект, вы быстро поймете новые функции и сможете разрабатывать приложения для iOS продвинутого уровня. Новички могут быстро освоить Swift, если уделят изучению нужное количество интереса и времени.
Разработчики iOS считают, что Swift — это простой способ для новичков начать работу с языком программирования. У Apple есть туториалы по программированию на Swift, которые богаты знаниями, доступными на их веб-сайте. Можно научиться программированию Swift с нуля без опыта программирования. Swift — лучший способ начать изучать программирование. У вас не возникнет проблем с пониманием кода Swift, как только вы освоите основы. Swift очень безопасен и требует меньше времени, потому что вам не нужно тратить много времени на отладку ошибок возникающих в процессе.
Можно ли научиться Swift самостоятельно?
Да, создатели сделали это так просто, что кажется, что вы изучаете новый язык. В изучении iOS-разработки нет ничего сложного; вы должны потратить хорошее время на обучение. Чем больше времени вы вложите, тем больше прибыли вы получите в будущем, в виде заработка на программировании. Во-первых, этот язык очень прост. Во-вторых, онлайн-курсы настолько лёгкие, что они упростили язык. Вам не нужно, чтобы кто-то вел вас шаг за шагом; вы можете учиться самостоятельно, улучшать свои знания и строить свое будущее на этом языке программирования.
Для начала попробуйте сами, посмотрев видео. Вы не сможете этому научиться, пока не попробуете на практике. Swift — это открытый исходный код, который позволяет вам добавлять новые функции; вы можете исправлять ошибки и улучшать существующие проекты. Поскольку для этого требуется меньше кода, вы можете легко научиться swift самостоятельно и решать любые проблемы профессионально.
Как быстро вы можете научиться программированию на Swift?
Если у вас есть опыт работы с языком программирования, вы можете быстро освоить swift и его расширенные функции за 3-4 дня. Но если вы новичок в мире программирования, вам потребуется 3-4 недели, чтобы изучить основы Swift и некоторые его дополнительные функции. Поскольку Swift — новый язык, он требует постоянных обновлений, новых функций и всего того, чего нет в старых версиях. Вы должны изучить его постоянно, поскольку с течением времени он улучшается и обновляется. Так что приготовьтесь потратить сотни часов на изучение swift кода iOS-разработки. Давайте объясним это простыми словами, вложите 5% в просмотр учебных пособий по Swift и чтение блогов, а 95% вложите в практику программирования и написания кода самостоятельно. Если вы начали изучать swift программирование, просматривая учебные пособия, вы можете пройти курс всего за 3 часа. Главное — попрактиковаться в программировании iOS-разработки. Чем больше вы будете делать примеров, тем быстрее вы научитесь.
Попробуйте no-code платформу AppMaster
AppMaster поможет создать любое веб, мобильное или серверное приложение в 10 раз быстрее и 3 раза дешевле
Начать бесплатно
Позвольте мне поделиться некоторыми полезными советами для быстрого и эффективного изучения языка iOS Swift.
- Начните с основ и освойтесь в них. Не двигайтесь вперед, пока не станете в них экспертом.
- Одну за другой начинайте изучать новые функции и добавляйте их коды к уже существующим. С помощью этого метода вы эффективно изучите новые функции и лучше их поймёте.
- Наберитесь терпения и разрабатывайте свое приложение или изучайте код Swift постепенно. Не пытайтесь сразу создать приложение для iOS. Таким образом, вы можете быстро отловить ошибки и избавиться от них без головной боли.
- Держите свою практику программирования в безопасности. Попробуйте писать коды из туториалов и постепенно делать свои. Не удаляйте ничего, из того, что вы сделали. Таким образом, вы будете учиться на своих ошибках.
- Продолжайте двигаться; не расстраивайтесь, если вам потребуется больше времени на обучение, чем другим. Помните, что все люди уникальны, и каждый имеет дело с разными сценариями. Последовательность сможет привести к цели, и благодаря решимости вы станете разработчиком iOS.
Легко ли программировать на Swift?
Когда вы работаете с языком программирования, вы должны писать сложный код и иметь дело со сложными функциями. Становится трудно поддерживать строки комментариев. Swift сделал это более эффективным и простым, поскольку представил новые функции, которые требуют на 15% меньше практики программирования, чем другие языки. Вы будете удивлены его технологией; он позволяет копировать и вставлять изображения, рисунки и данные из iOS в macOS.
Доступно множество готовых шаблонов, которые позволят вам редактировать код в соответствии с вашими требованиями. Нет необходимости писать коды с нуля; вы можете использовать шаблон и создать свое приложение за короткий период. Создание приложения с нуля может быть дорогостоящим и трудоемким процессом, тогда как использование шаблона приложения Xcode позволяет разрабатывать уже написанные коды и создавать новое приложение по доступной цене. Эти шаблоны имеют все функции, такие как меню, визуальные эффекты и макеты. Вы можете просто отредактировать функции в соответствии с вашими требованиями, прочитав инструкции. Эти шаблоны отзывчивы и дружелюбны. В Интернете доступно множество шаблонов; некоторые из них бесплатные, а некоторые платные. Вы можете использовать оба варианта; несмотря на то, что платный имеет больше возможностей, можно начать и с бесплатного шаблона и разработать хорошо функциональное приложение.
Вывод
По мере роста популярности разработки приложений основные части приложений для iOS успешно пишутся на Swift. Как разработчик iOS, вы можете выделиться из толпы, если знаете, как программировать на Swift и имеете опыт работы со Swift. Есть некоторые недостатки, но Apple ежедневно обновляет их, чтобы исправить. Однако плюсов больше, чем мелких минусов, которых даже и не будет в будущем, если предположить, что Swift будет расти в хит-парадах в ближайшие годы.
Помимо традиционных языков программирования, таких как Swift, существуют альтернативные пути разработки, такие как low-code или no-code программирование . Эти подходы придерживаются концепции низкого входа. Это означает, что вам нужно тратить гораздо меньше времени и усилий на изучение этих подходов к разработке. Такое быстрое развитие помогает программистам начать свою карьеру и расти как профессионалам. Несмотря на простоту входа, не стоит думать, что на платформах no-code можно создавать только простые MVP и пет-проекты. Это не так. Предположим, мы говорим о такой платформе, как AppMaster. В настоящее время это самый мощный инструмент no-code на рынке, инструмент «три в одном». Вы можете создавать веб-приложения, мобильные приложения и серверную часть. Помимо исходного кода, платформа также напишет для вас техническую документацию. Разве не здорово больше не тратить время на рутинные задачи и документацию, а полностью посвятить себя интересным исследованиям и продумыванию архитектуры приложения?
Создать Playground
Запустим Xcode и создадим Playground. Назовем его “BasicSwift”:
File → New → Playground…
⌥⇧⌘N
Swift Playground – это такой тип файлов, который представляет из себя игровую площадку для ваших экспериментов с кодом Swift. Результат исполнения каждой строчки кода вы можете наблюдать в боковой панели (Sidebar).
Переменные, константы, типы
Переменные обозначаются с помощью ключевого слова var
var hello = "Hello Proglib"
Чтобы объявить константу используется ключевое слово let
let brandName = "Proglib"
Swift – это статистический типизированный язык, а это значит, что мы должно явно задать тип каждой переменной во время компиляции.
Указывать тип переменной необязательно. Компилятор Swift автоматически его определит. Эта особенность называется интерференцией типов(type inference).
Swift предлагает следующие базовые типы: Int или UInt, Double, Float, String, Character, Bool, Tuples, Optional.
Множество типов фундаментально и чаще всего используется для объявления переменных. Забегая вперед скажу, что вы также можете создавать и свои собственные типы.
Мы не будет детально разбирать их все! Посвятим этой теме следующую 30-ти минутку.
Укажем тип нашей константы.
let brandName: String = "Proglib"
Интерполяция строк
Давайте теперь выведем имя бренда в консоль при помощи функции print()
.
print(brandName)
Интерполяция – это способ объединить переменные и константы внутри строки.
Теперь присвоим переменной hello
новое значение, и выведем в консоль.
hello = "Hello (brandName)"
print(hello)
Вот еще пример:
let name = "Ivan"
var age: UInt8 = 30
print("(hello). My name is (name). I am (age)")
Базовые операторы
Здесь все интуитивно. Предлагаю вам поэкспериментировать с ними самостоятельно и посмотреть на результаты.
Арифметические операторы
+ | сложение |
— | вычитание |
/ | деление |
% | деление по модулю |
var a = 1, b = 2
var result = a + b
// etc
Операторы присвоения
= , +=, -=, /=, %=
var h = 10
h += 1
h /= 2
h %= 2
// etc
Операторы сравнения
Операторы сравнения в качестве результата возвращают значения типа Bool
==, ≠, >, <, ≥, ≤
let condition = 2 > 3
let condition2 = 1 != 0
let resultCondition = condition == condition2
// etc
Логические операторы
Логические операторы используют для комбинирования или инверсии булевых значений.
Рассмотрим на примере:
// логическое И
print(true && true) // true
print(true && false) // false
// логическое ИЛИ
print(true || false) // true
// логическое НЕ – инвертирует булево значение
print(!true) // false
Это еще не все операторы, которые существуют в Swift. Остальные мы рассмотрим в контексте целей их предназначения.
Коллекции
Swift предлагает нам три основных типа коллекций: Array(Массивы), Dictionary(Словари) и Set(Множества). Сейчас мы рассмотрим первые два.
Array
Используйте квадратные скобки [], чтобы создавать массивы(Array) и словари(Dictionary).
Получить доступ к элементам массива можно написав индекс внутри скобок.
let digits: [UInt8] = [0, 1, 2, 3, 4, 5, 6, 7, 8 ,9]
print(digits[3])
Попробуйте изменить значение в массиве digits
. Что произойдет?
digits[0] = 1
🪲
Cannot assign through subscript: ‘digits’ is a ‘let’ constant
Поскольку мы объявили массив как константу, то и все его значения становится не изменчивыми (immutable), как и его размер. А если мы объявим массив как переменную, то он будет изменчивым (mutable). Такое свойство называют изменчивостью коллекций (mutability of collection).
Это утверждение справедливо и для Словарей.
// mutable
var numbers = [50, 10, 20, 34, 45]
print(numbers[0])
numbers[0] = numbers[0] + 1
Dictionary<Key, Value>
Создадим словарь sunSystemData
, в который добавим данные о солнечной системе.
Пусть ключами (key) данного словаря будут номера объектов солнечной системы, а значениями (value) названия объектов. Поскольку звезда рождается первой, то будем считать, что ключ со значением 0
всегда указывает на звезду. Остальные объекты следуют в порядке по отношению к звезде.
var sunSystemData = [ 0: "Sun", 1:"Mercury", 2:"Venus",
3:"Earth", 4:"Mars", 5:"Jupiter", 6:"Saturn", 7:"Uranus", 8:"Neptune"]
Мы не указали типы для словаря явно. Вы можете проверить как их определил Swift, используя функцию стандартной библиотеки Swift (Swift Standard Library) type(of: T)
.
type(of: sunSystemData) // Dictionary<Int, String>
Обратиться к элементу словаря можно, написав ключ внутри скобок. Результат будет содержать значение опционального типа (Optional), а если по заданному ключу (в скобках) нет соответствующего элемента, то получим nil
.
nil
в Swift означает отсутствие значения.
Получим нашу родную планету и выведем ее в консоль.
var homePlanet = sunSystemData[3]
print("My home is (homePlanet)")
Когда мы попытались вывести переменную в консоль, то получили предупреждение!
🪲
String interpolation produces a debug description for an optional value; did you mean to make this explicit?
Давайте посмотрим какой именно тип приняла переменная.
type(of: homePlanet) // Optional<String>
Чтобы избавиться от предупреждения в интерполяции строки, нам необходимо указать что именно мы выводим. Сделать это можно при помощи оператора as
. В этом случаи мы увидим напечатанный nil
, когда значение отсутствует. Попробуйте обратиться к элементу с ключом 0
.
print("My home is (sunSystem[0] as String?)") // My home is nil
print("My home is (homePlanet as String?)") // My home is Earth
Другим решением может быть присвоение переменной значения по умолчанию.
Сделать это мы можем при помощи оператора объединения по nil
– ??
var homePlanet = sunSystem[3] ?? "Unknown planet"
print("My home is (homePlanet)") // My home is Earth
Пока опустим темы об опциональных типах и приведении типов(type casting).
В следующих статьях я расскажу о них подробней.
Продолжим!
Кстати, если вы считаете, что Плутон это планета, то можете добавить её самостоятельно!
sunSystem[9] = "Pluto"
Чем отличаются массивы от словарей?
- Массивы хранят множество значений определенного типа в упорядоченном списке. Любое значение может присутствовать несколько раз в списке.
- Словари хранят множество значение определенного типа, где каждое значение связано с уникальным ключом, который идентифицирует это значение внутри словаря. Элементы в словаре не имеют определенного порядка, как в массивах.
Используйте словари, как вы их используете в реальном мире. Когда вам необходимо искать значения на основе их идентификатора (ключа).
Например:
var HierarchyOfNumbers: [Character:String] = [
"N":"Natural Numbers"
"Z":"Integers"
"Q":"Rational Numbers"
"R":"Real Numbers"
"C":"Complex Numbers"
]
Управление потоком
Часто необходимо выполнять различный код базирующийся на определенных условий (conditions).
- Если вам необходимо написать различную логику, которая зависит от определенных условий, тогда используйте условные инструкции
if
,switch
. Инструкцияif
хорошо подходит для простых сравнений, и нескольких вариантов исходов. - Инструкция
switch
подходит для более сложных условий. Лучше использовать ее, когда вам необходимо выбрать из множества вариантов альтернатив, основываясь на каком-либо значении, т.е. выполнить код соответствующий определенному шаблону. - Когда вам необходимо многократно повторить какие либо инструкции, используйте циклы:
for-in,
while
.
If…else
Инструкция if
бывает трех форм.
Традиционное ее представление выглядит так:
var condition = true
if condition {
//
} else {
//
}
В зависимости от условия, мы попадаем в определенные блоки кода. Когда условие истинно(true), выполняется блок следующий за if
, а когда ложно(false), выполняется блок следующий за else
.
Например, вы решили, что Плутон планета? Сейчас узнаем!
var isPluto = sunSystemData[9] != nil
if isPluto {
print("Pluto is planet")
} else {
print("Pluto is not planet")
}
if…
Мы можем опустить блок else
, когда нам необходимо выполнить только одно условие.
Рассмотрим такой случай. У нас есть данные, и мы не хотим перезаписать значение. Тогда необходимо проверить наличие данных, и только после добавить значение.
var key = 0, value = "Sun"
var isExists = sunSystemData[key] != nil // false
if !isExists { // true
sunSystemData[key] = value
}
if…else if…else
Также мы можем добавить условия следующее за else
.
var value = 0
if value > 0 {
print("(value)")
} else if value == 0 {
print(value)
} else {
print(value)
}
Вы можете комбинировать if else
.
Например:
var a = 0, b = 3, c = 1
if a > b {
print(a - b)
} else if b > a {
print(b - a)
} else if c < a {
print(a - c)
} else {
print(a + b + c)
}
switch
В самой простой форме switch
выглядит так:
var value = "R2-D2"
switch value {
case "R2-D2": print("Take him!")
case "C-3PO": print("Take him!")
default:
print("These aren't the droids you're looking for.")
}
Ключевое слово case
определяет возможный случай (шаблон), с которым сравнивается значение value
. Затем исполняется соответствующий блок кода на основе первого успешно совпавшего шаблона. В случаи если совпадений не найдено, исполняется блок default
, который всегда следует после остальных случаев. Условие default
гарантирует что наша конструкция полная и законченная.
Поменяйте значение value
, и посмотрите, какой блок кода исполнился.
for-in
Цикл for-in
упрощает перебор по последовательностям, т.к. массивы, словари, строки.
Синтаксис for-in
выглядит так:
for value in sequence{
//
}
Цикл for-in
исполняет инструкции определенное количества раз, пока мы не достигнем конца последовательности.
value
– элемент последовательности на каждой итерации(iteration, повторении).
Рассмотрим пример перебора значений массива и словаря.
for digit in digits {
print(digit)
}
for (key, value) in sunSystemData {
print("Key:(key) Value:(value)")
}
while
while
имеет две формы.
Первая из них начинается с вычисления условия. Такой цикл можно рассматривать как повторяющаяся инструкция if
.
var condition = true;
while (condition) {
// тело цикла
}
Например, мы хотим пройти 10 000 шагов.
var stepGoal = 10_000
var mySteps = 0
while mySteps < 10_000 {
mySteps += 1
}
Цикл будет работать пока условие mySteps < 10_000
принимает булево значение true
.
Внутри тела цикла мы увеличиваем переменную mySteps
на один шаг.
Когда условие принимает значение false
, то цикл останавливается.
Расчет факториала числа.
var counter = 5
var factorial = 1 // начальное значение
while counter > 0 {
factorial *= counter
counter -= 1
}
print(factorial)
Здесь я вам предлагаю разобраться самостоятельно
Вторая форма исполняет тело цикла прежде, чем вычислит условие. Следовательно, мы можем быть уверены что тело цикла выполняется один раз.
В остальном repeat-while
ведет себя идентично while
.
var condition = true
repeat {
// тело цикла
} while (condition)
Также цикл while
используется, когда нам заранее неизвестно число итераций последовательности. В отличии от цикла for-in
.
Функции
В Swift есть два типа функций:
Пользовательские(User-defined Function) и функции стандартной библиотеки (Standard Library Functions).
Функции помогают организовывать код, разбив его на более мелкие части, что делает код более легким для понимания и переиспользования. Мы уже использовали функции стандартной библиотеки, такие как print()
и type()
. Рассмотрим, как создаются пользовательские функции.
Функция – блок кода, который выполняет конкретную задачу.
Каждая функция имеет уникальное имя, которое является ее идентификатором.
func functionName(parameters) -> returnType {
// тело функии
}
Объявить функцию можно при помощи ключевого слова func
.
За ним следует имя функции – functionName
.
В скобках указываются параметры(parameters) функции.
Параметр – это значение определенного типа, принимаемое функцией.
returnType
– указывает, какого типа значение возвращает функция
Чтобы исполнить функцию, ее необходимо вызвать (как мы уже делали это с print()
).
// вызов функции
functionName()
Функции без параметров
Функции в которые мы не передаем параметры, называются функциями без параметров. Например, приветствие, которое мы написали в самом начале может быть организовано в виде функции.
func greetings() {
print("Hello Proglib!")
}
greetings()
print("Done!")
Мы объявили функцию с именем greetings()
, которая просто печатает "Hello Proglib!"
в консоли. Она не имеет параметров и возвращаемого значения. При вызове функции управление программой переходит к определению функции. Затем исполняется код, который содержится внутри тела функции:
print("Hello Proglib!")
Как только функция завершится, управление потоком переходит к следующей инструкции после вызова функции.
print("Done!")
Функции с параметрами
Функции, в которым мы передаем аргументы, называются функциями с параметрами. Если мы хотим, чтобы функция возвращала значение, нужно использовать оператор return
.
Например, разница между двумя значениями:
func difference(a: Int, b: Int) -> Int {
return a - b
}
var result = difference(a: 3, b: 2)
print(result)
Мы объявили функцию с именем difference
, которая принимает два параметра типа Int
и возвращает значение типа → Int
. При вызове функции, мы передаем параметры в круглых скобках (a: 3, b: 2)
.
Каждый параметр функции состоит из метки аргумента и имени параметра. Имена параметров используются при реализации функции.
func difference(of a: Int, less b: Int) -> Int {
return a - b
}
Метка аргумента используется при вызове функции.
difference(of: 1, less: 2)
По умолчанию параметры используют свое имя параметра в качестве метки аргумента(как в первом примере).
Если вам не нужна метка для аргумента, то напишите _
вместо конкретного названия метки для аргумента.
func difference(_ x: Int, _ y: Int) -> Int {
return x - y
}
difference(3, 4)
Мы можем опустить оператор return
, когда тело функции является одним выражением.
func difference(a: Int, b: Int) -> Int {
a - b
}
Заключение
Мы познакомились с фундаментальным синтаксисом языка программирования Swift. Рассмотрели основные операторы, научились объявлять переменные и объединять код в функции. В следующие полчаса разберем каждую тему более глубоко. На сегодня все! Playground доступен на Github.