Optional позволяет переменной любого типа представить ситуацию "отсутствие значения". В Objective-C «отсутствие значения» было доступно только в ссылочных типах с использованием специального значения nil. У типов-значений (value types), вроде int или float, такой возможности не было. Swift расширил концепцию «отсутствия значения» на типы-значения. Переменная optional может содержать либо значение, либо nil, сигнализирующее об отсутствии значения.
Optional Swift фактически реализуются с использованием перечислений (enums - вещи, которые имеют дискретный набор значений). В swift перечисления для каждого дискретного значения (case) могут иметь ассоциированные значениям (associated values). Enum optional имеет два значения: none и some, у
some
есть значение, указанное внутри необязательного.
Нулевые ссылки - буквально, когда переменная не имеет значения - были изобретены Тони Хоар еще в 1965 году при разработке ALGOL.
Сэр Чарльз Энтони Ричард Хоар (Тони Хоар) наиболее известен за алгоритмы QuickSort
Проверка типов в массивах и определение того, что там нет ошибок - трудоемко в плане производительности, поэтому было принято решение костылить Null. Он ускорял работу, избавлял программу от проверок, уменьшал ее размер, но приводил к проверкам на Null.
Когда его спросили о нем в ретроспективе, он сказал: «Я называю это своей ошибкой на миллиард долларов», потому что они приводят к очень большому количеству проблем.
-
None
- Нет никакой разницы, Optional.none (кратко .none) и nil эквивалентны. Фактически, следующий оператор вернёт true:nil == .none
Nil
(alias для.none
) - В swiftnil
всегда означаетnot set
. Optional имеет 2 состояния: set (установлен) и not set (не установлен) - nilИспользование nil более общепринято и рекомендовано
-
NaN
- этоnot a number
или несуществующее число. Получается, когда бесконечность делим на бесконечность или извлекаем корень из отрицательного числа. -
В большинстве ЯП
NULL
- это нулевой указатель
Ответ: ассоциативное значение (associated value) в enum! Не путать с associated type в Protocol (PATs)
Подробнее почитать про это. -> Beginner-> устный вопрос -> 5
Всего 7 способов развернуть optional.
1)_Принудительное развёртывание (forced unwrapping) — небезопасно.
- ✔️ Force unwrapping
- ✔️ Когда следует принудительно развернуть опции в Swift?
- ❎ Swift: Banning force unwrapping optionals
let a: String = x!
2)_Неявное развертывание (implicitly unwrapped optional) — небезопасно.
- ✔️ Implicitly unwrapped optionals
- ✔️ Why does Swift need both implicitly unwrapped optionals and regular optionals?
var a = x!
--или--
var a: Int! = nil
3)_Optional chaining — безопасно.
let names = ["John", "Paul", "George", "Ringo"]
let beatle = names.first?.uppercased()
first
вернет первое имя массива если оно есть или вернет nil. Если она вернет nil, то Swift не будет пытаться использовать uppercased()
и сразу установит beatle
= nil
4)_Optional binding — безопасно.
if let a = x {
print("x was successfully unwrapped and is = \(a)")
}
Но это не то же самое, что и:
func yearAlbumReleased(name: String) -> Int? {
if name == "Red" { return 2012 } else { return nil }
}
var year = yearAlbumReleased(name: "Red")
if year == nil {
print("There was an error")
} else {
print("It was released in \(year)")
// "It was released in Optional(2012)", потому что это не то же саме что и if let year = year { print("There wasn't an error") }
// можно сделать print("It was released in \(year!)"), чтобы вывод был таким, как нам нужно
}
x обязательно должен быть опционалом. x: String - ошибка компиляции, x: String? - корректно
5)_Оператор Guard — безопасно.
guard let a = x else {
return
}
Альтернатива if let - это guard let, которая также разворачивает опционалы. Отличия:
- guard let развертывает элемент с использованием return, который означает, что вы выйдете из функции, цикла или условия, в котором вы его использовали если развернуть не удалось.
- развернутый необязательный параметр остается пригодным для использования после guard кода.
6)_Nil coalescing operator — безопасно.
let a = first() ?? second() ?? ""
Это запустит first(), и если это вернет nil, попытается запустить second(), и если это вернет nil, тогда будет использоваться пустая строка.
Чтение ключа словаря всегда будет возвращать nil если такого ключа нет, поэтому вы можете использовать здесь nil coalescing:
let scores = ["Picard": 800, "Data": 7000, "Troi": 900]
let crusherScore = scores["Crusher"] ?? 0
--или--
let crusherScore = scores["Crusher", default: 0]
7)_Optional pattern — безопасно.
if case let a? = x {
print(a)
}
Indirect Enum Theme) | Back To iOSWiki Contents | 5.3.1.4.4 Collections And Tuple Theme Folder