• отладочное_сообщение ->String — выражение, текстовое значение которого будет выведено на отладочную консоль при остановке программы. Необязательный параметр.
Функция «утверждает», что переданное ей выражение возвращает логическое значение true. В этом случае выполнение программы продолжается, в ином (если возвращен false) — выполнение программы завершается, и в отладочную консоль выводится сообщение
Пример
// утверждение с двумя аргументами
assert( someVar> 100, "Данные неверны" )
// утверждение с одним аргументом
assert( anotherVar<= 10 )
Оператор условия if
Утверждения, с которыми вы только что познакомились, являются упрощенной формой оператора условия. Они анализируют переданное выражение и позволяют либо продолжить выполнение программы, либо завершить его (возможно, с выводом отладочного сообщения). Оператор if позволяет определить логику вызова блоков кода (исполнять или не исполнять) в зависимости от значения переданного выражения. Данный оператор используется повсеместно, благодаря ему можно совершать именно те действия, которые необходимы для получения корректного результата. К примеру, если пользователь нажал кнопку «Умножить», то необходимо именно перемножить, а не сложить числа. Оператор условия if имеет четыре формы записи, различающихся по синтаксису и функциональным возможностям:
сокращенная;
стандартная;
расширенная;
тернарная.
Тернарный оператор условия
Swift позволяет значительно упростить стандартную форму записи оператора if всего до нескольких символов. Данная форма называется тернарным оператором условия. Его отличительной особенностью является то, что он не просто выполняет соответствующее выражение, но и возвращает результат его работы.
СИНТАКСИС
проверяемое_выражение ? выражение_1 : выражение_2
проверяемое_выражение ->Bool — вычисляемое выражение, на основании значения которого принимается решение об исполнении кода, находящегося в блоке.
• выражение_1 ->Any — выражение, значение которого будет возвращено, если проверяемое выражение вернет true.
• выражение_2 ->Any — выражение, значение которого будет возвращено, если проверяемое выражение вернет false.
Пример
var y = ( x> 100 ? 100 : 50 )
В данном примере в переменной y будет инициализировано значение одного из выражений (100 или 50)
11. Оператор if для опционалов. Опциональное связывание. Оператор раннего выхода guard.
Это сделать достаточно просто: берём оператор сравнения "if" и задаём условие. Спрашиваем: эй, переменная, ты nil или не nil?
Если она отвечает "я сейчас nil, пустая", тогда ничего от неё не требуем. Разве что можно вывести на экран информацию о том, что значение переменной сейчас отсутствует, nil. Назовём это действие чистосердечным признанием! Если же переменная не nil, тогда её можно использовать в последующих действиях. Пример:
if optSample ==nil {
print ("optSample is nil")
} else {
print (optSample)
}
В части "if" мы задаём вопрос на проверку: если он положительный, то программа сообщает нам об этом, зажигает красный свет на дальнейшее использование. Если же значение не nil, то мы уже можем выполнять с ним те или иные действия. В данном случае мы просто выводим это имеющееся значение на экран.
Оператор guard называется оператором досрочного выхода . Подобно оператору if он проверяет истинность переданного ему условия . Отличие его в том, что он выполняет код в теле оператора только в том случае, если условие вернуло значение false .
СИНТАКСИС
guard проверяемое_условие else {
// тело оператора
}
После ключевого слова guard следует некоторое проверяемое утверждение.Если утверждение возвращае тtrue,то телооператора игнорируется и управление переходит следующему за guard коду. Если утверждение возвращает false,то выполняется код внутри телаоператора. Для данного оператора существует ограничение:его тело должно содержать один изследующих операторов—return,break,continue,throw.
.Оператор ветвления switch
Предположим, что в зависимости от полученной пользователем оценки стоит задача вывести определенный текст. Реализуем логику с использованием оператора if
Для этого можно использовать расширенный синтаксис оператора if, многократно повторяя блоки elseif.
СИНТАКСИС
switchпроверяемое_выражение {
case значение_1:
// первый блок кода
case значение_2, значение_3:
// второй блок кода
...
caseзначение_N:
// N-й блок кода
default:
// блок кода по умолчанию
}
• проверяемое_выражение ->Any — вычисляемое выражение, значение которого Swift будет искать среди case-блоков. Может возвращать значение любого типа.
• значение:Any — значение, которое может вернуть проверяемое выражение. Должно иметь тот же тип данных.
Ключевое слово fallthrough
С помощью ключевого слова fallthrough можно изменить логику функционирования оператора switch и не прерывать его работу после выполнения кода в case-блоке. Данное ключевое слово позволяет перейти к телу последующего case-блока. Рассмотрим следующий пример: представьте, что существует три уровня готовности к чрезвычайным ситуациям — А, Б и В. Каждая степень предусматривает выполнение ряда мероприятий, причем каждый последующий уровень включает в себя мероприятия предыдущих уровней. Минимальный уровень — это В, максимальный — А (включает в себя мероприятия уровней В и Б).
Реализуем программу, выводящую на консоль все мероприятия, соответствующие текущему уровню готовности к ЧС. Так как мероприятия повторяются от уровня к уровню, то можно реализовать задуманное с помощью оператора switch с использованием ключевого слова fallthrough
При значении "Б" переменной level на консоль выводятся строки, соответствующие значениям "Б" и "В". Когда программа встречает ключевое слово fallthrough, она переходит к выполнению кода следующего case-блока.
Ключевое слово where в операторе switch
Представьте, что в задаче про вольеры для драконов появилось дополнительное условие: поместить дракона в вольер № 3 можно только при условии, что в нем находятся менее пяти особей. Для хранения количества драконов будет использоваться дополнительная переменная. Включать в кортеж третий элемент и проверять его значение было бы неправильно с точки зрения логики, так как количество драконов не имеет ничего общего с характеристиками конкретного дракона. С одной стороны, данный функционал можно реализовать с помощью конструкции if-else внутри последнего case-блока, но наиболее правильным вариантом станет использование ключевого слова where, позволяющего указать дополнительные требования, в том числе к значениям внешних параметров
Ключевое слово where и дополнительные условия указываются в caseблоке для каждого значения отдельно. После where следует выражение, которое должно вернуть true или false. Тело блока будет выполнено, когда одновременно совпадет значение, указанное после case, и условие после where вернет true.
Вы можете использовать кортежи для проверки нескольких значений в одном switch. Каждый элемент кортежа может быть сравнён с разными значениями или интервалами значений. Используйте символ нижнего подчёркивания (_) (wildcard) для сравнения с любым возможным значением.
Кортеж представляет собой упорядоченный список из двух или более значений. Например:
let flight = (747, "SFO")
Тип константы flight (Int, String). После определения кортежа вы не можете изменить его порядок или тип. Кортежи идеально подходят для передачи нескольких связанных значений в одну переменную.
Вы можете получить доступ к значениям кортежа с помощью индекса:
print(flight.1)
// Output: SFO
Также можно использовать значения кортежа:
let flight = (airplane: 747, airport: "SFO")
print(flgith.airplane)
// Output: 747
Мы можем использовать кортежи вместе с оператором switch:
for i in 1...100 {
switch (i % 3 == 0, i % 5 == 0) {
case (true, false):
print("Fizz")
case (false, true):
print("Buzz")
case (true, true):
print("FizzBuzz")
default:
print(i)
}
}
В приведенном выше коде мы создаем кортеж из двух значений: результат вычисления i % 3 == 0 и результат вычисления i % 5 == 0. Теперь мы можем учитывать различные значения кортежей: (true, false), (false, true), (true, true). Если ни один из этих случаев не совпадает, мы выводим значение i.
Поскольку мы используем switch для проверки значений кортежа, мы также можем проверять различные совпадающие значения в кортеже:
let airplane = (type: "737-800", heading: "LAX")
switch airplane {
case ("737-800", _):
print("Этот самолет модели 737-800.")
case (let type, "LAX"):
print("Этот \(type) летит в аэропорт Лос-Анджелеса.")
default:
print("Неизвестный самолет.")
}
// Этот самолет модели 737-800.
В приведенном выше коде мы отвечаем 3 разных случая.
Выражение let type называется связыванием значения. Это позволяет нам привязать значение кортежа к константе. Теперь внутри case блока вы можете использовать эту константу, например, распечатать ее.
14. Последовательности. Коллекции. Массивы: способы создания массива. Доступ к элементам массива. Явное и неявное указание типа элементов массива.
Последовательность (Sequence) — набор элементов, выстроенных в очередь, в котором есть возможность осуществлять последовательный (поочередный) доступ к ним. При этом не предусмотрен механизм, позволяющий обратиться к какому-либо определенному элементу. Вы, как было сказано выше, можете лишь последовательно перебирать элементы последовательности. Sequence — это название протокола в Swift, который определяет требования к последовательностям. Если какой-либо тип данных принимает к реализации протокол (выполняет его требования), то значение этого типа (экземпляр) можно назвать последовательностью. Протокол Sequence требует, чтобы тип данных обеспечивал хранение множества однотипных значений и организовывал последовательный доступ к ним с помощью последовательного перебора. Коллекция (Collection) — это последовательность (Sequence), в которой можно обращаться к отдельному элементу напрямую. Другими словами, Collection — это протокол, основанный на протоколе Sequence, который при этом имеет дополнительное требование по обеспечению прямого доступа к элементам. Помимо этого, коллекция не может быть бесконечной (в отличие от Sequence). Для доступа к элементам коллекции используются индексы (indicies). Они могут быть представлены как в виде обычного числового значения (порядковый номер элемента), так и в виде более сложных структур (как, например, в словарях или строках, но об этом поговорим позже). На рис. 7.5 приведена упрощенная схема классификации рассмотренных протоколов и их требований.
Рис. 7.5. Классификация протоколов и их требования
В будущем вы научитесь создавать собственные типы данных, основанные на последовательностях и коллекциях. А сейчас необходимо уделить особое внимание информации, находящейся в этой части книги, так как приведенный материал достаточно важен и будет регулярно использоваться в будущем.
Массивы: способы создания массива.
Создание массива с помощью литерала
Значение массива задается с помощью литерала массива, в котором через запятую перечисляются значения элементов
СИНТАКСИС [значение_1, значение_2, ..., значение_N]
• значение: Any — значение очередного элемента массива, может быть произвольного типа данных. Литерал массива возвращает массив, состоящий из N элементов, значения которых имеют один и тот же тип данных. Литерал обрамляется квадратными скобками, а значения элементов в нем отделяются друг от друга запятыми. Массив может содержать любое количество элементов одного типа. Тип данных значений — произвольный, определяется вами в соответствии с контекстом задачи. Индексы элементов определяются автоматически в зависимости от порядка следования элементов.
Пример [1,1,2,3,5,8,12] В данном примере тип данных значения каждого элемента массива — Int. Массив имеет 7 элементов. Первые два (с индексами 0 и 1) имеют одинаковые значения — 1. Значение последнего элемента массива с индексом 6 равно 12.
Создание массива с помощью Array(arrayLiteral:)
Для создания массива помимо передачи литерала массива можно использовать специальные глобальные функции, одной из которых является Array(arrayLiteral:).
СИНТАКСИС Array(arrayLiteral: значение_1, значение_2, ...,значение_N)
• значение: Any — значение очередного элемента массива, может быть произвольного типа данных. Функция возвращает массив, состоящий из N элементов, значения которых имеют один и тот же тип данных. Значения произвольного типа передаются в виде списка в качестве входного параметра arrayLiteral. Каждое значение отделяется от последующего запятой.
Пример Array(arrayLiteral: 1, 1, 2, 3, 5, 8, 12)
В данном примере в результате выполнения функции будет возвращен массив, состоящий из 7 целочисленных элементов.
Создание массива с помощью Array(_:)
Также для создания массива можно использовать глобальную функцию Array(_:), которой в качестве входного аргумента необходимо передать произвольную последовательность (Sequence).
СИНТАКСИС Array(последовательность_значений)
• последовательность_значений: Sequence — последовательность элементов, которая будет преобразована в массив. Функция возвращает массив, состоящий из элементов, входящих в переданную последовательность. Последовательность значений, переданная в функцию.
Сұрақ. Создание пустого массива. Сравнение, слияние массивов. Многомерные массивы.
Создание пустого массива
Массив может иметь пустое значение, то есть не иметь элементов (это словно строка без символов). Для создания пустого массива можно использовать один из следующих способов:
явно указать тип создаваемого массива и передать ему значение [];
использовать специальную функцию [типДанных](), где типДанных определяет тип значений элементов массива.
Сравнение массивов
Массивы, так же как и значения фундаментальных типов данных, можно сравнивать друг с другом. Два массива являются эквивалентными:
если количество элементов в сравниваемых массивах одинаково;
если каждая соответствующая пара элементов эквивалентна (имеет одни и те же типы данных и значения).
Слияние массивов
Со значением массива, как и со значениями фундаментальных типов данных, можно проводить различные операции. Одной из них является операция слияния, при которой значения двух массивов сливаются в одно, образуя новый массив. Обратите внимание на несколько моментов:
результирующий массив будет содержать значения из обоих массивов, но индексы этих значений могут не совпадать с родительскими;
значения элементов подлежащих слиянию массивов должны иметь один и тот же тип данных.