Руководство по Swift для абсолютных новичков

Руководство по Swift для абсолютных новичков

Почему Swift?

На случай, если вы еще не слышали, Apple недавно представила новый язык для разработчиков iOS и OS X под названием Swift. Как оказалось, Swift разрабатывался с 2010 года, а это 2 года после выпуска первого SDK. Apple видела ограниченность Objective-C, которому уже почти 30 лет, и решила, что пришло время для перемен. Тем не менее, по подлинной манере Apple, они не хотели выпускать полусырой язык. Они поняли, что несмотря на недостатки Objective-C, они еще могут выйти за пределы возможного с ним, и так они и сделали.

Прошло шесть лет с момента выхода первого SDK и 1,2 млн. приложений были опубликованы в App Store. Миллионы разработчиков со страданием изучали тайной синтаксис и ограничения Objective-C. В последнее время, во весь голос говоря о своих бедах от устаревшего языка.

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

Когда речь идет о Swift, Apple ссылается на три ключевые парадигмы: Безопасность, Современность и Мощность. Swift впитал в себе все эти пункты. Ниже приведены основы, которые помогут приступить к работе со Swift. Если вы уже знаете какой-нибудь язык программирования, вы увидите много общего с другими современными языками. Вероятно, вы даже задумаетесь, зачем нужно было изобретать совершенно новый язык, но это уже обсуждение для другой записи в блоге.

Как пользоваться Swift?

Во-первых, вам придется скачать и установить Xcode 6. После того как вы установили его, откройте и выберите в меню File -> New -> File -> выберите слева источник, систему iOS или OSX -> Playground. Дайте имя вашему Playground, и все вы готовы начать работу.

Кроме того, как альтернативу, можно использовать REPL (Read Evaluate Print Loop) из терминала.

Инструкция для запуска в терминале:

  1. Откройте Терминал
  2. Если у вас есть две или более версий установленных Xcode, то вам нужно будет выбрать Xcode 6 в качестве версии по умолчанию. Если у вас только Xcode 6, тогда перейдите к шагу 3, а в противном случае идите дальше и выполните следующую строку:
     
    sudo xcode-select -s /Applications/Xcode6-Beta.app/Contents/Developer/

    На момент написания этого поста, бета-версия Xcode 6 называлась "Xcode6-Beta". Пожалуйста, проверьте имя вашего приложения в папке "Приложения" и выпишите соответствующий путь при использовании xcode-select.

  3. Чтобы запустить REPL напечатайте:
     
    xcrun swift

Основы

Переменные

Как и в любом языке программирования у нас есть переменные, которые позволяют хранить данные. Чтобы объявить переменную вы должны использовать ключевое слово var.

var greeting: String = "Hello World"

Приведенный выше код указывает системе, что мы хотим создать переменную с именем greeting, которая имеет тип String, и будет содержать текст "Hello World".

Swift достаточно умен, чтобы догадаться, что, если вы присваиваете строку в переменную, то переменная будет иметь тип String. Таким образом, вы не должны явно указывать тип, как в приведенном выше примере. А лучший и распространенный способ написания приведенного выше примера будет выглядеть так:

var greeting = "Hello World" // Предугадан тип String

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

  1. var greeting = "Hello World" // Предугадан тип String
  2. greeting = "Hello Swift"

Во время разработки приложения, есть много случаев, когда вы не хотите, чтобы значение переменной изменялось после его инициализации. Apple всегда имела два варианта типов: mutable и immutable. Mutable означает, что переменная может быть изменена а immutable - что она не подлежит изменению. Apple предпочитает immutable по умолчанию, что означает, что значения не будут меняться. Это делает ваше приложение быстрее и безопаснее в многопоточной среде. Чтобы создать неизменяемую переменную вам нужно использовать ключевое слово let.

Если мы изменим наш пример приветствия, используя let вместо var, то вторая строка даст нам ошибку компиляции, поскольку мы не можем изменить значение greeting.

  1. let greeting = "Hello World"
  2. greeting = "Hello Swift" // Ошибка компиляции

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

  1. let languageName: String = "Swift"
  2. var version: Double = 1.0
  3. let introduced: Int = 2014
  4. let isAwesome: Bool = true

Приведенный выше пример не только показывает нам различные типы, которые доступны в Swift, но он также показывает нам причину для использования let. Все значения кроме номера версии языка Swift остаются константами. Вы можете возразить, что isAwesome спорное понятие, но я дам вам прийти к этому выводу когда вы дойдете до конца этого поста.

Поскольку тип предугадывается мы можем просто написать:

  1. let languageName = "Swift" // предугадан как String
  2. var version = 1.0 // предугадан как Double
  3. let introduced = 2014 // предугадан как Int
  4. let isAwesome = true // предугадан как Bool

Строки

В нашем примере выше мы уже писали тип String. Давайте посмотрим, как мы можем соединить две строки с помощью оператора + .

  1. let title = "Руководство по Swift для абсолютных новичков"
  2. let review = "Он потрясающий!"
  3. let description = title + " - " + review
  4. // description = "Руководство по Swift для абсолютных новичков - Он потрясающий!"

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

  1. let datePublished = "19 Июля , 2014"
  2. let postMeta = "Запись в блоге опубликована: \(datePublished)"
  3. // postMeta = "Запись в блоге опубликована: 19 Июля, 2014"

Во всех приведенных выше примерах, я использую ключевое слово let, а это значит, что вы не сможете изменить строку, после того, мы как ее создали. Тем не менее, если вам нужно изменить строку, то просто используйте ключевое слово var.

Другие типы

Кроме строк у нас есть Int для целых чисел. Double и Float для чисел с плавающей точкой и Bool для булевых значений, таких как: true или false. Эти типы предугадываются точно так же как и строки, так что вы не обязаны явно указать их при создании переменной.

Float и Double различаются по точности и по величине хранимого числа.

  • Float: представляет собой 32-разрядное число с плавающей точкой , но точность Float может быть всего лишь 6 десятичных цифр.
  • Double: представляет собой 64-разрядное число с плавающей точкой и имеет точность не менее 15 десятичных цифр.

По умолчанию, когда мы пишем число с плавающей точкой, компилятор предугадывает его как Double.

var version = 1.0 // предугадывает как Double

Но вы можете явно указать Float.

var version: Float = 1.0

Типы коллекций

Массив

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

  1. var cardNames : [String] = ["Jack", "Queen", "King"]
  2. // Swift может предугадать [String] так что мы можем также написать:
  3. var cardNames = ["Jack", "Queen", "King"] // предугадан как [String]

Вы можете создать два типа массива: массив с одним типом или массив с несколькими типами. Swift страстно увлечен безопасностью, так что он предпочитает первый тип, но может реализовать и второй тип с помощью универсальных типов. В приведенном выше примере массив содержит одни строки, это означает, что это массив с одним типом.

Для доступа к элементу массива нужно использовать индекс:

println(cardNames[0])

Примечание: мы использовали выше функцию println, которая печатает значение "Jack" в консоль, а затем добавит символ новой строки.

Изменение массива

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

var todo = ["Написать блог","Сделать форум"]

Убедитесь, что вы используете ключевое слово var, чтобы мы могли изменить наш массив.

Чтобы добавить еще один элемент к нашему массиву todo, мы используем оператор '+=' :

todo += ["Сходить в магазин"]

Чтобы добавить несколько элементов в наш массив todo мы просто добавляем массив:

todo += ["Отправить письмо", "Постирать вещи"]

Чтобы заменить существующий элемент массива просто укажите индекс этого элемента и присвойте новое значение:

todo[0] = "Корректировать запись в блоге"

Чтобы заменить диапазон элементов:

todo[2..<5] = ["Постирать вещи", "Сходить в магазин", "Приготовить ужин"]

Словарь

Другим типом коллекций является Cловарь, который похож на хеш-таблицу из других языков программирования. Словарь позволяет хранить пары ключ-значение и получить доступ к значению, передавая ключ.

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

var cards = ["Jack" : 11, "Queen" : 12, "King" : 13]

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

Изменение словаря

Что, если мы хотим добавить "Ace" в наш словарь cards? Все, что нам нужно сделать, это использовать ключ в качестве индекса и присвоить ему значение. Примечание: cards объявляется как var, что означает, что он может быть изменен.

cards["Ace"] = 15

Мы сделали ошибку и хотим изменить значение "Ace". Еще раз просто используйте ключ в качестве индекса и присвойте ему новое значение.

cards["Ace"] = 1

Чтобы извлечь значение из словаря

println(cards["Ace"])

Управление потоком

Циклы

Насколько хороша коллекция, если мы не можем пройтись циклом по нему? Swift для этого дает нам while, do-while, for и for-in циклы. Давайте рассмотрим каждый из них.

Самым простым из них является while цикл в котором говорится: пока что-то истинно, выполняй блок кода. Он останавливает выполнение, когда его условие превращается в ложь.

  1. while !complete {
  2.  println("Загрузка...")
  3. }

Примечание: восклицательный знак перед переменной complete обозначает отрицание и читается как противоположное значение complete.

Кроме того, есть цикл do-while, который гарантирует, что ваш блок кода выполнится по крайней мере один раз.

  1. var message = "Начало загрузки"
  2. do {
  3.  println(message)
  4.  message = "Загрузка.."
  5. } while !complete

Последующие вызовы выражения println будут печатать "Загрузка.."

Есть еще обычный for цикл, где можно указать число, условие и инкремент:

  1. for var i = 1; i < cardNames.count; ++i {
  2.  println(cardNames[i])
  3. }

Или вы можете просто использовать for-in, он создает временную переменную и присваивает ей значение каждого элемента во время прохода по массиву.

  1. for cardName in cardNames {
  2.  println(cardName)
  3. }

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

Например:

  • 1...10 - это диапазон чисел от 1 до 10. Три точки называются замкнутым диапазоном, потому что последнее число включается в диапазон.
  • 1..<10 - это диапазон чисел от 1 до 9. Две точки со знаком меньше, называется полузакрытый диапазон, потому что последнее число не включается в диапазон.

Давайте распечатаем таблицу умножения на 2 используя for-in с диапазоном:

  1. for number in 1...10 {
  2.  println("\(number) умножить на 2 будет \(number*2)")
  3. }

Мы также можем перебрать словарь cards, чтобы распечатать оба ключ и значение:

  1. for (cardName, cardValue) in cards {
  2.  println("\(cardName) = \(cardValue)")
  3. }

If выражение

Чтобы контролировать поток нашего кода мы, естественно, имеем if выражение.

  1. if cardValue == 11 {
  2.  println("Jack")
  3. } else if cardValue == 12 {

     

  4.  println("Queen")
  5. } else {
  6.  println("Не найдено")
  7. }

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

Выражение switch

Switch выражение в Swift является очень гибким и имеет много особенностей. Некоторые основные правила выражения switch:

  • Оно не требует break, после каждого case выражения
  • Switch не ограничивается целочисленными значениями. Вы можете искать соответствие для любых значений, таких как: String, Int, Double или любых похожих объектов.
  • Выражение switch должно соответствовать хотя бы одному возможному значению, если нет, то вы должны указать блок default , что делает ваш код более безопасным. Если вы не напишите case для хотя бы одного возможного значения или блок default, то вы получите ошибку компиляции: "switch должен быть исчерпывающим".
  1. switch cardValue {
  2.  case 11:
  3.   println("Jack")
  4.  case 12:
  5.   println("Queen")
  6.  default:
  7.   println("Не найдено")
  8. }

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

  1. switch distance {
  2.  case 0:
  3.   println("не является допустимым расстоянием")
  4.  case 1,2,3,4,5:
  5.   println("рядом")
  6.  case 6,7,8,9,10:
  7.   println("далеко")
  8.  default:
  9.   println("слишком далеко")
  10. }

Есть моменты, когда даже несколько значений тоже мало. Для тех случаев, вы можете использовать диапазоны. А что, если, любое расстояние больше 10 и меньше 100 считается далеко?

  1. switch distance {
  2.  case 0:
  3.   println("не является допустимым расстоянием")
  4.  case 1..<10:
  5.   println("рядом")
  6.  case 10..<100:
  7.   println("далеко")
  8.  default:
  9.   println("слишком далеко")
  10. }

Сможете ли вы догадаться, что приведенный выше код будет печатать?

Функции

Мы использовали println во многих наших примерах. Он является примером того, как использовать функцию. Но как мы можем создать свою собственную функцию?

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

  1. func printCard() {
  2.  println("Queen")
  3. }

Что хорошего в функции, если она всегда будет просто печатать "Queen" в качестве имени карты? Что делать, если мы хотим передать ему параметр, чтобы он мог напечатать любое имя карты?

  1. func printCard(cardName: String) {
  2.  println(cardName)
  3. }

Конечно, мы не ограничены только одним параметром. Мы можем передать несколько параметров:

  1. func printCard(cardName: String, cardValue: Int) {
  2.  println("\(cardName) = \(cardValue)")
  3. }

Что, если мы просто хотим, чтобы наша функция создала строку и возвратила его значение, вместо того чтобы напечатать его? Тогда мы можем использовать ключевое слово return, и указать тип возвращаемого значения с помощью стрелки -> в конце объявления функции.

  1. func buildCard( cardName: String, cardValue: Int) -> String {
  2.  return "\(cardName) = \(cardValue)"
  3. }

В блоке кода выше мы говорим, что мы создаем функцию с именем buildCard, которая принимает два параметра и возвращает тип String.

Заключение

Если вы дошли до этого места, то примите наши поздравления! Теперь вы хорошо разбираетесь в основах Swift. Это довольно много для усвоения, но это только вершина айсберга, из всего на что Swift способен. На самом деле нам еще учиться и учиться. Оставайтесь с нами для получения свежих материалов!