Skip to content

Latest commit

 

History

History
150 lines (102 loc) · 9.33 KB

File metadata and controls

150 lines (102 loc) · 9.33 KB

Optional

  1. ✔️ 100 Days of SwiftUI. Day 12
  2. ✔️ Unwrapping optionals

Что такое optional и какие проблемы они решают?

Optional позволяет переменной любого типа представить ситуацию "отсутствие значения". В Objective-C «отсутствие значения» было доступно только в ссылочных типах с использованием специального значения nil. У типов-значений (value types), вроде int или float, такой возможности не было. Swift расширил концепцию «отсутствия значения» на типы-значения. Переменная optional может содержать либо значение, либо nil, сигнализирующее об отсутствии значения.

Optional Swift фактически реализуются с использованием перечислений (enums - вещи, которые имеют дискретный набор значений). В swift перечисления для каждого дискретного значения (case) могут иметь ассоциированные значениям (associated values). Enum optional имеет два значения: none и some, у some есть значение, указанное внутри необязательного.

Изобретение NULL

Нулевые ссылки - буквально, когда переменная не имеет значения - были изобретены Тони Хоар еще в 1965 году при разработке ALGOL.

Сэр Чарльз Энтони Ричард Хоар (Тони Хоар) наиболее известен за алгоритмы QuickSort

Проверка типов в массивах и определение того, что там нет ошибок - трудоемко в плане производительности, поэтому было принято решение костылить Null. Он ускорял работу, избавлял программу от проверок, уменьшал ее размер, но приводил к проверкам на Null.

Когда его спросили о нем в ретроспективе, он сказал: «Я называю это своей ошибкой на миллиард долларов», потому что они приводят к очень большому количеству проблем.

В чём разница между NaN, Null, nil и .none?

  • None - Нет никакой разницы, Optional.none (кратко .none) и nil эквивалентны. Фактически, следующий оператор вернёт true: nil == .none

    • Nil (alias для .none) - В swift nil всегда означает not set. Optional имеет 2 состояния: set (установлен) и not set (не установлен) - nil

      Использование nil более общепринято и рекомендовано

  • NaN - это not a number или несуществующее число. Получается, когда бесконечность делим на бесконечность или извлекаем корень из отрицательного числа.

  • В большинстве ЯП NULL - это нулевой указатель

Подходы к созданию Null

Почему мы можем применять optional ко всем типам?

Ответ: ассоциативное значение (associated value) в enum! Не путать с associated type в Protocol (PATs)

Развертывание опционала

Подробнее почитать про это. -> Beginner-> устный вопрос -> 5

Всего 7 способов развернуть optional.

1)_Принудительное развёртывание (forced unwrapping) — небезопасно.

  1. ✔️ Force unwrapping
  2. ✔️ Когда следует принудительно развернуть опции в Swift?
  3. Swift: Banning force unwrapping optionals
let a: String = x!

2)_Неявное развертывание (implicitly unwrapped optional) — небезопасно.

  1. ✔️ Implicitly unwrapped optionals
  2. ✔️ Why does Swift need both implicitly unwrapped optionals and regular optionals?
var a = x!
--или--
var a: Int! = nil

3)_Optional chaining — безопасно.

  1. ✔️ Optional chaining
  2. ✔️ Why is optional chaining so important?
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 — безопасно.

  1. ✔️ Unwrapping with guard
guard let a = x else {
  return
}

Альтернатива if let - это guard let, которая также разворачивает опционалы. Отличия:

  1. guard let развертывает элемент с использованием return, который означает, что вы выйдете из функции, цикла или условия, в котором вы его использовали если развернуть не удалось.
  2. развернутый необязательный параметр остается пригодным для использования после guard кода.

6)_Nil coalescing operator — безопасно.

  1. ✔️ Nil coalescing
  2. ✔️ When should you use nil coalescing in Swift?
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