--- title: 2.2. Типы данных. Необязательные типы. tags: Templates, Talk description: View the slide with "Slide Mode". --- Тема занятия: # 2.2. Логические типы и операции с ними. Опциональные (необязательные) типы. # План занятия 1. Логические типы 1. Операции сравнения 1. Логические операции 1. Опциональные типы --- # Вспоминаем прошлые занятия - Как называется возможность в программе Xcode изучать код, не создавая проект для разработки? - Как инициализировать переменную, константу? - Какая между ними разница? - Какие типы данных вы изучили на прошлом занятии? - Есть ли вопросы по домашнему заданию? --- ## Логические значения (Bool) Тип Bool представляет логическое значение true (истина) или false (ложь). То есть объект Bool может находиться в двух состояниях: ```javascript= var isEnabled: Bool = true isEnabled = false ``` Объекты типа Bool нередко являются результатом условных выражений, то есть таких выражений, которые представляют некоторое условие, и в зависимости от истинности условия возвращают true или false: true — если условие истинно и false — если условие ложно. Например, как здесь: ![](https://i.imgur.com/RZYVFj8.jpg) --- ## Операции сравнения Сравнивая значения, мы получим либо истину, либо ложь. Следуя этому высказываю, мы понимаем, что результат сравнения это переменная типа Bool. - `==` Операция равенства. Если левое и правое значение равны, вернет true, иначе false: ```javascript= var a = 20 var b = 20 var c = a == b print(c) // true, так как a равно b var d = 8 c = a==d print(c) // false, так как a не равно d ``` - `!=` Операция неравенства. Если левое и правое значение не равны, вернет true, иначе false: ```javascript= var a = 20 var b = 20 var c = a != b print(c) // false, так как a равно b var d = 8 c = a!=d print(c) // true, так как a не равно d ``` - `>` Если левое значение больше правого, вернет true, иначе false ```javascript= var a = 25 var b = 20 var c = a > b print(c) // true, так как a больше чем b var d = 8 c = d > a print(c) // false, так как d меньше чем a ``` - `<` Если правое значение больше левого, вернет true, иначе false: ```javascript= var a = 25 var b = 20 var c = a < b print(c) // false, так как a больше чем b var d = 8 c = d < a print(c) // true, так как d меньше чем a ``` - `>=` Если левое значение больше либо равно правому, вернет true, иначе false: ```javascript= var a = 20 var b = 20 var c = a >= b print(c) // true, так как a равно b var d = 8 c = d >= a print(c) // false, так как d меньше чем a ``` - `<=` Если правое значение больше либо равно левому, вернет true, иначе false: ```javascript= var a = 25 var b = 20 var c = a <= b print(c) // false, так как a больше чем b var d = 9 c = d <= a print(c) // true, так как d меньше a ``` ## Логические операции При программировании бывают случаи, когда код должен выполняться или наоборот не выполняться, тогда на помощь приходят логические операции. Данные операции работают с переменными типа Bool и возвращают такую же переменную. - ! Отрицание (НЕ). Меняет значение Bool переменной на обратное: ```javascript= var isEnabled: Bool = true var result = !isEnabled // false ``` - && Логическое Умножение (И). Если оба значения буду равны true, тогда вернет true, иначе false: ```javascript= let isEnabled: Bool = true let isAlive = true let result = isEnabled && isAlive // true - так как оба операнда равны true ``` ```javascript= let a: Bool = true let b: Bool = false let c: Bool = true let d = a && b && c // false, так как b = false ``` - || Логическое сложение (ИЛИ). Если хотя бы одно значение равно true, вернет true, иначе false: ```javascript= var isEnabled: Bool = true var isAlive = false isEnabled || isAlive // true, так как isEnabled равен true ``` ```javascript= var a: Bool = true var b: Bool = false var c: Bool = false a || b || c // true, так как a = true ``` Так же логические операции можно объединить с операциями сравнения: ```javascript= let a = 10 let b = 12 let c = a > 8 && b < 10 let d = a > 8 || b < 10 print(c) // false print(d) // true ``` --- ##  Опциональные типы данных (опционалы) Опциональные типы данных -- это такие объекты в коде, которые могут отсутствовать. Инициализация таких объектов может не выполняться, по умолчанию такой объект равен nil. Обозначается опционал добавлением к типу данных знака `?`. Рассмотрим пример: ```javascript= let someString = "123" let someNumber = Int(someString) ``` В данном примере мы преобразуем строку `someString` в число. Так как строка имеет числовое значение, ошибки не произойдет. Но что будет, если в строковой переменной будут символы? Тогда мы бы не смогли преобразовать переменную к числовому значению, и конструкция `Int(someString)` вернула нам `nil`. Следовательно наш объект имел бы тип переменно `Int?`, что означает опциональная переменная. Если мы хотим принудительно занулить переменную, мы можем это сделать фактически в коде. Например: ```javascript= var number: Int? = 12 number = nil // теперь переменная number не имеет значения ``` Значение nil может применяться только к объектам опциональных типов. Только опциональные объекты могут иметь значение `nil`. `Int?` - сокращенная запись от `Optional<Int>`. Примеры объявления опционалов: ```javascript= var number: Optional<Int> = 12 ``` В примере мы присвоили опциональной переменной значение 12, но на самом деле переменная имеет значение Optional(12): ```javascript= var number : Optional<Int> = Optional(12) // или так var number2 = Optional(12) ``` Нельзя забывать, что `Optional<Int>`, `Optional<String>`, `Optional<Double>` это разные типы данных. Например: ```javascript= var number = Optional(12) number = Optional("12") // Ошибка number представляет тип Optional<Int>, а не Optional<String> ``` ### Как получить значение из опционала? Работать с двумя разными объектами мы можем только в том случае, если они имеют одинаковые типы данных. Рассмотрим пример с ошибкой: ```javascript= var a: Int? = 12 var b: Int = 10 var c = a + b // ошибка — разные типы ``` В данном примере переменные имеют разные типы данных, одна из переменных опциональна. Для того чтобы данный пример выполнялся, нам нужно извлечь значение из опционала. Самый простой способ это поставить оператор `!` после объекта. Однако такой метод не является безопасным и использовать мы его можем только в том случае, если мы на 100% уверены, что в переменной есть данные как в примере. Оператор `!` так же имеет название **forced unwrap operator** или **unwrap operator**: ```javascript= var a: Int? = 12 var b: Int = 10 var c = a! + b // с = 22 ``` Другой пример: ```javascript= var b: Int = 10 var a: Int? = Int("123") b = a! + b print(a!) // 123 print(b) // 133 ``` ### Неявное получение значений Optional Получить значение можно еще одним способом: ```javascript= var b: Int = 10 var a: Int! = Int("123") b = a + b print(a) // 123 print(b) // 133 ``` Здесь значение переменной сразу объявляется как `Int!`. Это тоже опционал, только указывающий, что в нем всегда есть значение. Так делать не стоит, потому что данные могут отсутствовать, что приведет к ошибке. ### Проверка Optional на nil Одна из лучших возможностей получить значение опциональной переменной — это сравнить её с `nil`. Для сравнения будем проверять через конструкцию `if`. Ее общая форма: ```javascript= if var переменная | let константа = опциональное_значение { действия1 } else { действия2 } ``` Форма очень простая: * в условии `if` мы присваиваем значение переменной/константе; * если значение есть, то выполнится данный блок с действием1. * Но, если опционал имеет значение `nil`, выполнится действие2. Например: ```javascript= var str: String = "123" var b: Int = 10 if var a = Int(str) { a+=b print(a) } else { print(b) } ``` В данном примере, если строковое значение состоит только из чисел, выполнится блок: ```javascript= a+=b print(a) ``` Иначе: ```javascript= else { print(b) } ``` Так же можно сравнить переменную со значением `nil`: ```javascript= var str: String = "123" var b: Int = 10 var a: Int? = Int(str) if a != nil { a+=b print(a) } else { print(b) } ``` Если надо проверить значения нескольких переменных или констант, то все их можно указать в одном выражении `if`: ```javascript= let a = Int("123") let b = Int("456") if let aVal = a, let bVal = b { print(aVal) print(bVal) } else { print("Error") } ``` В этом примере блок `if` выполнится только при условии, что обе опциональные переменные не равны `nil`. В любом другом случае выполнится блок `else`. ### Сравнение объектов Optional Если сравнить Optional с объектом конкретного типа, например с числом, в данном случае объект будет так же преобразован к типу Optional: ```javascript= let a: Int? = 10 if a == 10 { print("a is equal to 10") } else { print("a is not equal to 10") } ``` Так же работают операции `==` и `!=`. Но с операциями `<`, `>`, `<=`, `>=` все происходит по другому. Посмотрите следующий код, он выдаст ошибку: ```javascript= let a: Int? = 10 if a > 5 { print("a is greater than 5") } ``` В таких случаях нужно поставить оператор `!` или извлечь значение, как мы с вами делали выше: ```javascript= let a: Int? = 10 if a != nil && a! > 5 { print("a is greater than 5") } ``` ### Optional в switch..case В конструкции `switch` можно использовать объект Optional, в таком случае в блоках `case` нужно использовать `?` для проверки значения, либо `nil` для проверки его отсутствия: ```javascript= let number = Int("55") switch number { case 55?: print("number is equal to 55") case let value?: print("number is equal to \(value)") case nil: print("number is undefined") } ``` ### Оператор nil-объединения Оператор `??` проверяет первый операнд на наличие значения. Если этого значения нет, то выполняется операнд, следующий после знаков `??`. ```javascript= let a = Int("234") let b = a ?? 10 print(b) // 234 ``` В этом примере переменная и будет равна 234, так как переменная a не равна nil. Данный оператор используется, когда есть значение по умолчанию, либо когда не уверен в том, что данные будут извлечены из Optional. --- # Итоги: - Узнали о логических типах и операциях с ними - Изучили работу с опционалами ___ ## Домашнее задание: ### Задача №1 #### Вы создаете приложение для учета работников компании. В нем есть данные о работнике: имя, фамилия, отчество (если есть), возраст, город. - создайте переменные и проинициализируйте их значениями - поменяйте возраст сотрудника и удалите отчество - Выведите все переменные в консоль (каждую с новой строки) - Дайте комментарий к каждой строчке кода ### Задача №2 #### - Создайте три опциональные строковые переменные. Первые две проинициализируйте значениями, оставшуюся переменную проинициализируйте значением nil. При помощи 'nil-coalescing' оператора выведите каждое значение в консоль с новой строки. Затем присвойте 3-й переменной значение и выведите его в консоль, используя 'nil-coalescing' оператор. Есть ли разница между выводами в случае, когда переменная не имела значения и после присвоения. - Создать пять строковых констант. Одни константы это только цифры, другие содержат еще и буквы. Найти сумму всех этих констант приведя их к Int (Используйте 'optional binding' и 'forced unwrapping') ### Задача №3 #### Используя данные из Задачи №.3 прошлого домашнего задания составить Операции сравнения и вывести в консоль результат выполнения (Все данные о разплате брать после повышения): - Зарплата первого больше зарплаты третьего - Зарплата второго меньше зарплаты первого - Зарплата первого больше зарплаты второго ИЛИ зарплата третьего меньше зарплаты второго - Зарплата третьего меньше зарплаты первого И Зарплата второго больше зарплаты первого ### Задача №4 #### Создайте опциональную константу с типом данных Optional<Int>. Проинициализируйте конструктором преобразования строки в целое число 'Int(String)'. Вместо 'String' впишите температуру за окном. При помощи конструкции 'if else' выведите в консоль информационные сообщения, например для таких случаев, температура: - Больше нуля - Меньше нуля - Меньше -10 градусов - Больше 10 градусов - Нет значения (nil) #### Например, если температура -25 градусов, можно вывести в косоль сообщение "Это что, Сибирь?" #### Попробуйте подставить различные значения в конструктор, чтобы увидеть в консоли все сообщения. ### Готовый файл формата .playground заархивируйте и загрузите в личном кабинете в формате .zip В презентации ссылка: https://github.com/netology-code/bios-homeworks/blob/master/2.2/README.md