---
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 — если условие ложно.
Например, как здесь:

---
## Операции сравнения
Сравнивая значения, мы получим либо истину, либо ложь. Следуя этому высказываю, мы понимаем, что результат сравнения это переменная типа 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