СПРАВОЧНИК ПО SWIFT

Часть 2: Основы

 

Ознакомительная текстовая информация для новичков.

 

СМОТРЕТЬ ВИДЕОУРОКИ

Вы здесь:

Основы

Swift – новый язык программирования для создания iOS и OS X приложений. Однако, многие части Swift могут быть вам знакомы из опыта разработки на С и Objectve-C.

Swift предоставляет свои собственные версии всех фундаментальных типов С и Objective-C, включая Int для целых, Double и Float для чисел с плавающей запятой, Bool для логических значений и String для текстовых данных. Swift также предоставляет мощные версии двух основных типов коллекций – Array (массив) и Dictionary (словарь), это описано в типах коллекций.

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

В дополнение к известным типам, Swift добавляет новые типы, которых нет в Objective-C. Они включают в себя кортежи (tuple), которые позволяют создавать и передавать группы значений. Кортежи могут возвращать множество значений из функции как одно составное значение.

Swift также добавляет опциональные типы, которые позволяют работать с отсутствием значения. Опциональные типы говорят или “у меня есть значение и оно равно х”, или “у меня вообще нет значения”. Опциональные значения схожи в использовании с nil и указателями в Objective C, но они работают для любого типа данных, а не только для классов. Опциональные значения безопаснее и выразительнее, чем nil-указатели в Objective-C и часто используются во многих мощных функциях Swift.

Опциональные типы – это пример того факта, что Swift является языком с типовой безопасностью (type safe). Swift помогает вашему коду быть ясным о типах значений, с которыми он работает. Если часть вашего кода ожидает строку, типовая безопасность предотвращает вас от передачи туда целого числа по ошибке. Это позволяет вам ловить и исправлять ошибки как можно раньше в процессе разработки.

Содержание

book

Инициализация пустой строки
Изменение строк
Строки это тип-значение
Работа с символами
Подсчет символов
Конкатенация строк и символов
Интерполяция строк
Сравнение строк
ПРОПИСНЫЕ и строчные буквы в строках
Юникод

Циклы for
for-in
For-условие-инкремент
Циклы while
While
Do-While
Условные выражения
If
Switch

null

Константы и переменные

Константы и переменные ассоциируют имя (например, maximumNumberOfLoginAttempts или welcomeMessage) со значением определенного типа (например, число 10 или строка “Hello”). Значение константы не может быть изменено после того, как было задано, тогда как переменная может быть изменена на другое значение в будущем.

Объявление констант и переменных

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

let maximumNumberOfLoginAttempts =10 
var currentLoginAttempt =0

Код можно прочитать как “объявите новую константу, названную maximumNumberOfLoginAttempts, и задайте ей значение 10. Затем объявите новую переменую, названную currentLoginAttempt, и дайте ей начальное значение 0.”

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

Вы можете объявить несколько констант или несколько переменных на одной строке, разделив их запятой:

var x =0.0, y =0.0, z =0.0

Если значение, которое вы храните, не будет меняться – всегда объявляйте его как константу, используя слово let. Используйте переменные только для хранения значений, которые должны меняться.

null

Аннотации (обозначения) типов

Вы можете добавить аннотацию типа, когда объявляете константу или переменную, чтобы точно обозначить тип значений, которые она может хранить. Аннотация типа отделяется двоеточием от названия переменной или константы. Приведем пример:

var welcomeMessage:String

Эту строку можно прочитать как “Объявите переменную, названную welcomeMessage, чтобы она хранила текстовые (String) значения”. Таким образом, мы показываем, какие именно значения будет содержать переменная (в данном случае – текст/строку).

Переменной welcomeMessage теперь можно присовить любое строковое значение, и это не вызовет ошибок:

welcomeMessage ="Hello"

На практике, обозначения типов придется писать редко. Если вы предоставите начальное знаение для переменной или константы, Swift почти всегда сможет сам распознать тип значений, которые она должна содержать. Это будет описано в разделе “Безопасность типов и подбор типов”. В примере с welcomeMessage, мы не предоставили начального значения, поэтому мы указываем тип явно.

null

Имена для констант и переменных

Вы можете использовать практически любые символы для названий констант и переменных, включая символы юникода:

let ?=3.14159
let ??="????"

Имена констант и переменных не могут содержать математических символов, стрелок, точек и некоторых символов Unicode (private-use or invalid Unicode code points), символов для рисования линий или прямоугольников. Они так же не могут начинаться с цифры, хотя в целом цифры можно использовать в любой другой части имени.

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

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

Вы можете поменять значение существующей переменной на другое значение того же типа. Например, поменяем friendlyWelcome с «Hello!» на «Bonjour!»:

var friendlyWelcome ="Hello!"
friendlyWelcome ="Bonjour!"// friendlyWelcome теперь содержит "Bonjour!"

В отличие от переменной, значение константы нельзя поменять после установки – в противном случае, компилятор выдаст ошибку:

let languageName ="Swift"
languageName ="Swift++"// тут мы получим ошибку, т.к. нельзя менять значение константы

null

Вывод значений констант и переменных на экран

Вы можете вывести текущее значение константы или переменной, используя функцию println:

println(friendlyWelcome)// получим на экране Bonjour!

println – это глобальная функция, которая выводит на экран значение, после чего делает переход на новую строку. Если вы работаете в XCode, к примеру, то это сообщение будет выведено в окошке “console” (консоль). Есть другая функция – print – она делает то же самое, что и println, но не переводит текст на новую строку

Вы можете напечатать с помощью println любую строку:

println("This is a string")

Функция println может печатать и более сложные сообщения, как и функция NSLog в Cocoa (знакомая для разработчиков Objective-C). Эти сообщения могут включать значения констант и переменных.

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

println("The current value of friendlyWelcome is \(friendlyWelcome)")// печатает The current value of friendlyWelcome is Bonjour!

Об остальных возможностях строкой интерполяции читайте в разделе “Интерполяция строк” на нашем сайте

null

Комментарии

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

Комментарии в Swift аналогичны комментариям в С. Однострочные комментарии начинаются с двух слэшей:

// это комментарий

Вы можете написать многострочный комментарий, начав его с символов /* и закончив */:

/* это тоже комментарий,
но он на нескольких строках */

В отличие от многострочных комментариев в С, многострочные комментарии в Swift могут быть вложенными:

/* начало комментария
/* а вот мы вложили комментарий
и закончили это вложение */
и закрыли первый комментарий*/

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

null

Точка с запятой

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

let cat ="cat"; 
println(cat);//печатает cat

null

Целые числа (тип Integer)

Целые числа (Integer) – это числа, не содержащие дробной части, например 42 или -23. Они так же могут быть знаковыми (положительными, отрицательными или нулем) или беззнаковыми (положительным или нулем).

Swift представляет целые числа в виде знаковых и беззнаковых целых с размерами в 8, 16, 32 и 64 бита. Эти целые числа следуют стандартному именованию в Си, то есть 8битное беззнаковое целое число имеет тип UInt8, 32битное знаковое число – Int32. Как и все типы в Swift, эти типы целых чисел должны начинаться с большой буквы.

Границы целых чисел

Вы можете получить минимальное и максимальное значение каждого числа с помощью свойств min и max:

let minValue =UInt8.min // минимальное значение равно 0 для этого типа
let maxValue =UInt8.max // максимальное значение равно 255 для этого типа

Значения этих свойств (0 и 255 в нашем случае) имеют тип самого свойства (UInt8 в нашем случае), соответственно minValue и maxValue автоматом становятся типа UInt8.

Int

В большинстве случаев, вам не придется выбирать специальный размер целого числа для использования в вашем коде – в Swift есть тип Int, который имеет тот же размер, что и “родной” размер слова для текущей платформы, а именно:

  • для 32битных платформ – Int имеет тот же размер, что и Int32
  • для 64битных платформ – Int имеет тот же размер, что и Int64

Если вам не нужно работать с особым размеров целых чисел, используйте Int для целых чисел в вашем коде – это позволяет коду быть последовательным и совместимым. Даже на 32 битных платформах, Int может хранить любое значение от -2 147 483 648 до 2 147 483 647 – что является достаточно большим для большинства задач.

UInt

Swift также предоставляет беззнаковый тип целых чисел UInt, который имеет тот же размер, что и “родной” размер слова на текущей платформе:

  • для 32битных платформ – UInt имеет тот же размер, что и UInt32
  • для 64битных платформ – UInt имеет тот же размер, что и UInt64

Используйте UInt только когда вам действительно нужен беззнаковый целый тип размером со слово (word) платформы. В других случаях, предпочтительнее использовать Int, даже если известно, что значения будут неотрицательными. Последовательное использование Int для целых чисел позволяет содержать код совместимым, избегает нужды в конвертации между разными типаци чисел и соответствует определению целого типа, как описано в разделе “Безопасность типов и подбор типов” на нашем сайте.

null

Числа с плавающей точкой

Числа с плавающей точкой – это числа, у которых есть дробная часть, например 3.14159, 0.1 и -273.15.

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

  • Double является 64битным числом с плавающей точкой – его следует использовать, когда значения должны быть очень большими или особенно точными
  • Float является 32битным числом с плавающей точкой – используйте во всех остальных случаях, когда высокая точность не требуется

Double имеет точность в минимум 15 десятичных знаков, тогда как Float – только 6. Подходящий для использования тип зависит от природы и диапазона значений, с которыми вам требуется работать.

null

Безопасность типов и подбор (inference) типов

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

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

Проверка типов позволяет вам избежать ошибок, когда вы работаете с разными типами значений. Однако, это не означает, что вам обязательно объявлять тип каждой константы или переменной – если вы не объявите тип сами, Swift использует подбор(inference) типа для определения подходящего типа. Интерфейс типа позволяет компилятору делать вывод о типе по операциям в вашем коде во время компиляции.

Из-за подбора типа, Swift требует гораздо меньше объявлений, чем языки типа С или Objective-C. Константы и переменные по прежнему явно типизированы, но большинство работы по определению типа сделано за вас.

Подбор типа особенно полезен, когда вы объявляете константу или переменную с начальным значением – это часто делается с помощью присвоения литерального значения (литерала) константе или переменной в момент ее объявления. Литерал – это просто значение, которое появляется в вашем коде, например 42 или 3.14159.

Например, если вы присваиваете литерал 42 новой константе без объявления ее типа, Swift автоматически догадывается, что тип вашей константы – Int, поскольку вы инициализируете ее числом, похожим на целое число:

let meaningOfLife =42// meaningOfLife автоматически становится Int

Точно так же, если вы не указываете тип для литерала с плавающей точкой, Swift предположит, что вы хотите использовать тип Double:

let pi =3.14159// pi имеет тип Double

Swift всегда выбирает Double, а не Float, если вы не указываете тип явно.

Если вы совместите в одной строке целочисленный литерал и литерал с плавающей точкой, тип будет также Double:

let anotherPi =3+0.14159// anotherPi - также Double

Литеральное значение 3 не имеет заданного типа, зато компилятор видит присутствие плавающей точки – поэтому и назначает тип Double.

null

Числовые литералы

Целоисленные литералы могут быть записаны как:

  • Десятичное число без префикса
  • Двоичное число с префиксом 0b
  • Восьмеричное число с префиксом 0o
  • Шестнадцатеричное число с префиксом 0x

Запишем число 17 каждым из способов:

let decimalInteger =17
let binaryInteger =0b10001// 17 в двоичном представлении
let octalInteger =0o21// 17 в восьмеричном представлении
let hexadecimalInteger =0x11// 17 в шестнадцатеричном представлении

Литералы с плавающей точкой могут быть десятичными (без префикса) или шестнадцатеричными (с префиксом 0x). Они обязаны всгеда иметь число (десятичное или шестнадцатеричное) с обеих сторон от точки. Они также могут иметь экспоненту, отделяемую от числа буквой e или E для десятичных и буквой p или P для шестнадцатеричных чисел.

Для десятичных чисел с экспонентой exp, базовое число умножается на 10exp:

  • 1.25e2 означает 1.25 X 102, или 125.0
  • 1.25e-2 означает 1.25 X 10-2, или 0.0125

Для шестнадцатеричных чисел с экспонентой exp, базовое число умножается на 2exp:

  • 0xFp2 означает 15 X 22, или 60.0
  • 0xFp-2 означает 15 X 2-2, или 3.72

Все следующие литералы с плавающей точкой имеют десятичное значение 12.1875:

let decimalDouble =12.1875
let exponentDouble =1.21875e1
let hexadecimalDouble =0xC.3p0

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

let paddedDouble =000.123.456
let oneMillion =1_000_000
let justOVerOneMillion =1_000_000.000_000_1

null

Конвертация числовых типов

Используйте тип Int для всех своих целочисленных констант и переменных, даже если известно, что они будут неотрицательными (разумеется, за исключением особых случаев). Использование стандартного целого типа в повседневных ситуациях означает, что целочисленные константы и переменные сразу могут взаимодействовать с автоподставляемым типом для целочисленных литеральных значений. (от переводчика – вообще, здесь говорится о том, что переменные становятся interoperable – в данном случае, имеется ввиду, что все наши константы и переменные, если они будут иметь тип Int, общепринятый в системе – смогут безопасно работать со всеми другими константами и переменными, зная, что они тоже Int).

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

Конвертация целых чисел

Диапазон чисел, которые можно хранить в целочисленной константе или переменной, отличается для каждого типа – например, в Int8 можно хранить числа от -128 до 127, тогда как в UInt8 – числа от 0 до 255. Число, которое не помещается в диапазон приемлемых чисел, вызовет ошибку на этапе компиляции, например:

let cannotBeNegative:UInt8=-1// UInt8 не может хранить отрицательных значений, тут будет ошибка
let tooBig:Int8=Int8.max +1// Int8 не может хранить число большее, чем максимальное значение, тут тоже ошибка

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

Чтобы сконвертировать один числовой тип в другой, вам необходимо инициализировать новое число желаемого типа с использованием существующего значение. В примере ниже, константа twoThousand имеет тип UInt16, тогда как константа one имеет тип UInt8. Их нельзя напрямую добавлять друг к другу, поскольку они не одного типа. Вместо этого, мы вызываем UInt16(one), чтобы создать новое значение типа UInt16, используя значение константы one:

let twoThousand:UInt16=2_000
let one:UInt8=1
let twoThousandAndOne = twoThousand +UInt16(one)

Поскольку оба складываемых значения в последней строчке кода имеют тип UInt16, компилятор позволяет выполнить сложение – и выходная константа twoThousandAndOne будет иметь тип UInt16 – поскольку компилятор видит, что ей присваивается значение суммы двух UInt16-констант.

SomeType(ofInitialValue) (т.е. выражение вида НазваниеТипа (начальноеЗначение) – прим. переводчика) – это стандартный способ вызвать инциализатор типа в Swift и передать начальное значение. У типа UInt16 есть инициализатор, принимающий значение UInt8, и этот инициализатор используется, чтобы создать новый UInt16 из существующего UInt8. Однако, любой тип передать не получится – только тот тип, для которого UInt16 имеет соответствующий инициализатор.

Конвертация целых чисел и чисел с плавающей точкой

Конвертация между целыми числами и числами с плавающей запятой должна быть явной:

let three =3
let pointOneFourOneFiveNine =0.14519
let pi =Double(three)+ pointOneFourOneFiveNine
// pi равно 3.14519 и он имеет автоматически определенный тип Double

Здесь, константа 3 используется для создания нового значения Double, таким образом в последней строке оба слагаемых имеют один тип. Без этой конвертации, сложение было бы невозможно (компилятор выдал бы ошибку).

Обратная конвертация также возможна, т.е. целочисленное значение можно инициализировать значением с плавающей точкой:

let integerPi =Int(pi)// integerPi равен 3, имеет тип Int

Для дробных значений, при конвертации в целое, просто отбрасывается дробная часть – т.е. 4.75 станет 4, -3.9 станет -3.

Правила для совмещения числовых констант и переменных отличаются от правил для числовый литералов. Литеральное значение 3 может быть добавлено напрямую к литеральному значению 0.14159, т.к. числовые литералы не имеют определенного типа – их тип определяется лишь когда они оцениваются компилятором.

null

Алиасы типов

Алиасы типов – это альтернативные имена для существующих типов. Их можно определить с помощью ключевого слова typealias.

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

typealias AudioSample=UInt16

Как только вы объявили алиас типа, вы можете испоьзовать его в любом месте, где вы использовали бы настоящее имя типа:

var maxAmplitudeFound =AudioSample.min
//maxAmplitudeFound теперь 0

В данном примере, мы объявили AudioSample как алиас для UInt16 и, поскольку это алиас, мы можем обращаться к AudioSample.min, который на самом деле вызывает UInt16.min, предоставляющий, в свою очередь, значение для нашей переменной.

null

Логический тип (boolean)

Swift имеет базовый логический тип, называемый Bool. Логический тип (он же – булевый тип) называется так, поскольку он может содержать только два зачения – true(правда) или false(ложь). Swift предоставляет две соответствующие константы – true и false:

let orangesAreOrange =true
let turnipsAreDelicious =false

Типы этих переменных – Bool, поскольку они инициализируются булевыми литеральными значениями, поэтому мы не объявляли их тип явно – это позволяет коду быть более читаемым.

Логические значения особенно полезны при работе с условными выражениями, например if:

if turnipsAreDelicious {
	println("ммм, вкусная репа!")}
else{
	println("фуу, репа ужасна!")}// напечатает "репа ужасна" (а лично я люблю репу! - прим. переводчика)

Условные выражения, такие как if, будут рассмотрены в главе “Управление контролем”.

Типовая безопасность языка предотвращает использование не-логических значений в выражениях, требующих логическое значение. Следующий пример (нормально компилирующийся в С и ObjectiveC), в Swift вызовет ошибку:

let i =1
if i {//тут будет ошибка}

Однако, альтернативный вариант будет корректным:

let i =1
if i == 1 {//тут все ок}

Результат сравнения i == 1 является логическим значением, поэтому второй пример проходит проверку типов. Сравнения описываются в следующей главе “базовые операторы”.

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

null

Кортежи (tuples)

Кортежи (tuples) группируют несколько значений в одно составное значение. Это значение внутри кортежа может иметь любой тип и значениям не обязательно всем быть одного типа.

В следующем примере, (404, “Not found”) – это кортеж, который описывает код ответа HTTP. Код ответа HTTP – это специальное значение, которое веб-сервер возвращает вам каждый раз, когда вы запрашиваете веб-страницу. Код 404 Not found значит, что запрашиваемая страница не найдена.

let http404Error =(404,"Not found")// http404Error имеет тип (Int, String) и равен (404, "Not found")

Кортеж (404, “Not found”) группирует Int и String для того, чтобы вернуть код ответа HTTP, состоящего из двух частей – номера и понятного человеку описания. Мы можем описать этот тип как “кортеж типа (Int, String)”.

Вы можете создавать кортежи из любой перестановки типов и они могут содержать сколько угодно нужных вам типов. Можно создать кортежи (Int, Int, Int) или (String, Bool), в общем – любой, какой вам нужно.

Вы можете разобрать (или декомпозировать, или разложить – decompose) компоненты кортежа в отдельные константы или переменные, чтобы использовать их:

let(statusCode, statusMessage)= http404Error
println("Код статуса \(statusCode)")// печатает "Код статуса 404"
println("Сообщение - \(statusMessage)")// печатает "Сообщене - Not found"

Если вам нужны лишь некоторые из значений кортежа, можно игнорировать его части, используя подчеркивание (_) при разложении кортежа:

let(justTheStatusCode, _)= http404Error
println("Код статуса \(justTheStatusCode)")// печатает "Код статуса 404"

Другой возможный вариант – доступ по индексу элемента, начиная от 0:

println("Код статуса \(http404Error.0)")// печатает "Код статуса 404"
println("Сообщение - \(http404Error.1)")// печатает "Сообщене - Not found"

Можно также дать индивидуальные имена элементам в кортеже при его объявлении:

let http200Status =(statusCode:200, description:"OK")

Если вы дали имена элементам в кортеже, вы можете использовать их, чтобы обращаться к этим элементам:

println("Код статуса \(http200Status.statusCode)")// печатает "Код статуса 200"
println("Сообщение - \(hhttp200Status.description)")// печатает "Сообщене - OK"

Кортежи особенно полезны, когда мы возвращаем значение из функций. ФФункция, которая скачивает веб страницу, может возвращать кортеж (Int, String) для обозначение успешности или неудачи совершенной операции. Возвращая кортеж с двумя значениями, каждое разного типа, функция предоставляет больше полезной информации о ее выполнении, чем если бы она возвращала какое-то одно значение. Для большей информации по теме, смотрите раздел “Функции с несколькими возвращемыми значениями” на нашем сайте.

Кортежи полезны для временных групп схожих значений. Они не предназначены для создания сложных структур данных. Если есть шанс, что ваши данные будут храниться в приложении некоторое время, лучше смоделировать их с помощью класса или структуры. Для большей информации на эту тему, почитайте раздел “Классы и структуры”.

null

Опциональные значения

Вы можете использовать опциональные знаения в ситуациях, где значение может отсутствовать. Опциональное значение говорит одно из двух:

  • или “у меня есть значение и оно равно х”
  • или ” у меня нет никакого значения”

 

Концепции опциональных значений не существует в С или Objective-C. Самое ближайшее в Objective-C – это возможность возвращать nil из метода, который возвращает объекты. nil как бы обозначает, что “корректный объект отсутствует”, однако это работает только объектов, но не для структур, базовых типов или перечислений. Для этих типов, Objective-C методы обычно возвращают какое-нибудь специальное значение (например, NSNotFound), чтобы обозначить отсутствие значения. Этот подход предполагает, что код, вызывающий метод, знает о том, что есть это специальное значение и что его нужно учитывать. ОПциональные значения в Swift позволяют вам указать возможность отсутствия значения для любого типа, без надобности использования дополнительных констант.

 

Приведем пример. Тип String имеет метод toInt, который пробует перевести содержимое строки в целочисленное значение типа Int. Однако, не каждая строка может быть сконвертирована вв целое число. Из строки “123” получается число 123, однако из строки “hello, world” нельзя получить целочисленного значения.

 

Пример ниже использует метод toInt, чтобы попробовать перевести строку в Int:

let possibleNumber ="123"
let convertedNumber = possibleNumber.toInt()// convertedNumber теперь имеет тип "Int?" (да-да, именно Int со знаком вопроса), или так называемый "опциональный Int"

 

Поскольку метод toInt может не сработать, он возвращает опциональный Int, а не обычный Int. Опциональный Int записывается как Int? – знак вопроса показывает, что значение является опциональным, т.е. переменная или константа типа Int? может или содержать какое-либо значение Int?, или не содержать никакого значения вообще. (Она не может содержать ничего другого, т.е. Bool, String и т.д. _не_ могут храниться в ней. Либо Int, либо ничего).

Условные выражения и вынужденная распаковка (forced unwrapping)

Вы можете использовать if, чтобы выяснить, содержит ли опциональное значение какое-либо значение. Если оно содержит, то оно вернет true, иначе – false.

Как только вы убедились, что опциональное значение содержит значение, вы можете обратиться к нему, используя восклицательный знак в конце имени. Он обозначает ” я знаю, что это опциональное значение определенно содержит значение – пожалуйста, используйте его”. Это и называется “вынужденная распаковка” (мы как бы принуждаем компилятор “распаковать” значение – прим. переводчика).

if convertedNumber {
    println("\(possibleNumber) имеет целочисленное значение \(convertedNumber!)")}
else{
    println("\(possibleNumber) не может быть сконвертирован в целое число")}// печатает на экран "123 имеет целочисленное значение 123"

 

Попытка использовать ! для того, чтобы достать значение в случаях, когда его нет в опциональном значении, вызовет ошибку времени исполнения (runtime error), т.е. ошибку во время работы приложения. Поэтому всегда убеждайтесь, что значение содержится, прежде чем использовать восклицательный знак.

 

Опциональная связка

Вы можете использовать опциональную связку, чтобы узнать, содержит ли опциональная переменная значение и если содержит, то сохранить его во временную константу или переменную. Опциональная связка может быть использована с if и while, чтобы проверить, что значение присутствует в опциональной переменной и извлечь его в константу или другую переменную одним действием. if и while описываются в разделе “Контроль управления” на нашем сайте.

Опциональные связки реализуются следующим образом:

if let constantName = someOptional {// если _название константы_ = _некоторая опциональная переменная_// код}// то есть если в опциональной переменной someOptional есть значение, оно пишется в constantName и код внутри if выполняется

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

if let actualNumber = possibleNumber.toInt(){
    println("\(possibleNumber) имеет целочисленное значение \(actualNumber)")}
else{
    println("\(possibleNumber) не может быть сконвертирован в целое число")}// печатает на экран "123 имеет целочисленное значение 123"

Этот код можно прочитать так:

“Если опциональный Int, возвращаемый методом possibleNumber.toInt, содержит значение, то создайте новую константу actualNumber со значением, которое там содержится”.

Если конвертация прошла успешно, actualNumber становится доступной в пределах первой ветки выражения if. Она уже инициализирована значением, поэтому нет нужды использовать восклицательный знак. В нашем примере мы просто выводим ее на экран.

Вы можете использовать как константы, так и переменные, для опциональной связки. Если вы хотите управлять значением actualNumber внутри вашего if, используйте var вместо let для объявления переменной, а не константы.

nil

Вы можете присвоить опциональной переменной состояние “без значения”, присвоив ей специальное значение nil:

var serverResponseCode:Int?=404//serverResponseCode содержит Int со значением 404
serverResponseCode =nil//serverResponseCode теперь не содержит значения

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

Если вы определите опциональную константу или переменную, не предоставив значения, она автоматически получит nil (отсутствие значения):

var surveyAnswer:String?// surveyAnswer автоматически является nil

В Swift nil – не то же самое, что nil в Objective C. Там nil является указателем на несуществующий объект, в Свифте же – это не указатель, а отсутствие значения определенного типа. Опциональные переменные/константы любого типа могут быть установлены в nil, а не только объекты.

Неявное развернутые опциональные значения (implicit unwrapped optionals)

Как описано выше, опциональные значения обозначают, что константа или переменная может не иметь никакого значения. Мы можем проверить это, используя if и получить значение, используя восклицательный знак или опциональную связку.

Иногда из структуры приложения видно, что опциональная переменная или константа будет всегда иметь значение после того, как оно впервые было установлено. В этих слчаях, полезно каким-то образом убрать нужду в проверке и “доставании” значения каждый раз, когда мы обращаемся к этой переменной.

Такие опциональные переменные определяются как “неявно развернутые”. Вы можете объявить неявно развернутую опциональную переменную, поставив восклицательный знак вместо вопросительного при объявлении типа.

НЕявно развернутые опциональные константы и переменные полезны, когда известно, что значение будет постоянно присутствовать в переменной или константе с какого-то момента. Основное использование таких опциональных переменных в Swift – при инициализации класса, как описывается в разделе “Ссылки без владельцев и неявно развернутые опциональные свойства” (позже вставим сюда ссылку, когда переведем).

Неявно развернутая опциональная константа или переменная – это обычная опциональная переменная в своей сути, но может быть использована как неопциональная, без необходимости “доставать” ее значение при каждом доступе. Лучше всего посмотреть на этот ад на примере:

let possibleString:String?="Опциональная строка"
println(possibleString!)// необходимо использовать восклицательный знак, чтобы получить доступ к значению// получим на экране "Опциональная строка"
let assumedString:String!="Неявно развернутая опциональная строка"
println(assumedString)// не требуется восклицательного знака для доступа// получаем на экране "Неявно развернутая опциональная строка"

Для удобства, можно считать, что неявно развернутая опциональная переменная или константа – это обычная опциональная переменная/константа, которой дано разрешения показывать свое значение автоматически, когда она используется. Вместо того, чтобы помещать восклицательный знак после опциональной переменной при каждом использовании, просто поместите восклицательный знак после названия типа при объявлении.

При попытке доступа к неявно развернутой опциональной переменной, когда она еще не получила значение, вы получите ошибку времени исполнения (runtime error). То же самое произойдет, если вы примените восклицательный знак к обычной опциональной переменной, которая не содержит значения.

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

if assumedString {
    println(assumedString)}// выводим на экран "Неявно развернутая опциональная строка"

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

if let definiteString = assumedString {
    println(definiteString)}// выводим на экран "Неявно развернутая опциональная строка"

НЕявно развернутая опциональная строка не должна использоваться в случаях, когда есть шанс, что переменная не будет содержать значения (будет nil) в какой-то момент времени. Всегда используйте обычный опциональный тип в случаях, если нужно проверять на nil в течении жизненного цикла переменной.

null

Утверждения (они же ассерты, они же assertions)

Опциональные типы позволяют проверять значения, которые могут существовать или отсутствовать, и писать код, который красиво обрабатывает отсутствие значения. Однако, в некоторых случаях код не может продолжить выполнение в случае, когда значение не существует или не удовлетворяет определенным условиям. В этих ситуациях, вы можете вызвать ассерт (trigger an assertion) – это остановит выполнение кода и дасть возможность провести отладку, чтобы выяснить, откуда взялось неподходящее значение.

Отладка с утверждениями

Утверждение – это проверка, проходящая во время исполнения, которая убеждается, что определенное логическое условие является правдой (true). Оно в буквальном смысле “утверждает”, что условие верно. Используйте утверждения, чтобы убедиться, что определенное условие обязательно соблюдается прежде, чем код исполняется. Если условие является правдой, код выполняется так, как и должен, а если нет, то приложение выключается.

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

Утверждение пишется, используя глобальную функцию assert. Ему передается функция или выражение, возвращающее true или false, а также сообщение, которое отображается в случае, когда результат выражения или функциии – false.

let age =-3
assert( age >=0,"Возраст человека не может быть меньше 0")// строчка выше заставляет сработать наше утверждение, т.к. возраст указан меньше нуля

В этом примере, исполнение кода продолжится только в случае, если возраст age >= 0, т.е. age должно быть неотрицательным. В случае, если оно отрицательно (как в нашем примере), утверждение будет неверным и завершит наше приложение.

Сообщение можно пропустить:

assert(age>=0)

При этом, сообщение для функции assert не может содержать интерполяцию строк.

Когда стоит использовать утверждения

Используйте их, когда условие потенциально может быть false, но должно обязательно быть true, чтобы код продолжил выполнение нормально. Вот пара примеров:

  • Индекс для обращения к элементу коллекции должен быть в пределах коллекции, но может быть выше или ниже пределов
  • Значение, передаваемое функции, некорректно и не позволяет нормально ее выполнить
  • Опциональная переменная содержит nil, но должна быть нe-nil для успешного выполнения кода.

Для более подробной информации смотрите также “Доступ к элементам коллекции” и “Функции” (как только мы их переведем..)

Утверждения завершают приложение, поэтому они являются эффективным способом, чтобы подсказать, что все необходимые условия всгеда соблюдаются в течение процесса разработки и отловить нужные ошибки, но перед публикацией приложения от них лучше избавиться (поскольку не очень правильно просто брать и вырубать приложение, не сообщив ничего пользователю).

Создайте свое приложение для iOS с нуля
SWIFT С НУЛЯ

Этот видео курс, который предназначен для новичков без опыта кодирования, и разработчикам с некоторым опытом программирования iOS. Коллекция видео уроков пополняется каждую неделю.

 

ТВОЕ ПЕРВОЕ iOS ПРИЛОЖЕНИЕ

На видео курсах вы создадите свое собственное приложение готовое к размещению в AppStore.

Учитесь, делая
app-1-26

Xcode 10
Вы познакомитесь с основными инструментами разработки iOS, включая Xcode, Interface Builder и Playgrounds.

app-2-26

Swift
Узнаете, как разработать приложение для iOS в Swift и создадите свое приложение, готовое к загрузке в AppStore.

app-3-26

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

Хотите перейти на следующий уровень?
Наши курсы помогут вам в этом. Хотите создавать 2D и 3D игры? Или разрабатывать приложения для Apple Watch? Нет ничего проще!

«Разработка 2D игр»

Разработка 2D игр на Swift

Целью данного курса является получение практических знаний и навыков в написании игр. Вы создадите 4 игры для своего портфолио.

 

ПЕРЕЙТИ К КУРСУ

«Разработка 3D игр»

mobile-game

Создание 3D игр с помощью SceneKit на iOS, watchOS, tvOS и macOS! Посмотрев курс вы поймете, что это легко! Вы создадите 3 игры для своего портфолио.

 

ПЕРЕЙТИ К КУРСУ

«Apple Watch»

watch_course_swift1

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

 

ПЕРЕЙТИ К КУРСУ

«Бесплатные вебинары»

webinars_main

Вебинары проходят каждый месяц! Научись программировать на Swift от уровня новичка до профи разработчика! Не забудь зарегистрироваться!

 

ПЕРЕЙТИ К КУРСУ

Изучайте, экспериментируйте, развивайтесь
Учебная библиотека. Наша цель — научить программировать и создавать приложение для iOS. Здесь вы можете найти коллекцию статей, которые помогут вам в изучении программирования для iOS.