Swift Часть 1: Быстрый старт

Если вы нашли опечатку в тексте, выделите ее и нажмите CTRL + ENTER.

Xcode: 
22
Swift: 
33

Эта статья будет полезна как новичкам, так и опытным программистам. Если вы новичок, то 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 (то, что наверху) View\Assistant Editor\Show 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