Implicitly Unwrapped Optional, в целом, ведут себя как Optional. На самом деле, они преобразовываются к Optional при каждом удобном случае:
let x: Int! = 42
let y = x // y has type Int?
Есть два отличия: во-первых, можно привести IUO к non-optional типу:
func f(_ arg: Int) { print(arg) }
let x: Int! = 42
let y: Int = x
let z = x as Int
f(x)
Во-вторых, можно вызывать на такой переменной методы самого объекта. Если в IUO содержится nil, то приложение упадёт с соответствующим сообщением:
struct Dog {
func bark() { print("Woof!") }
}
let d: Dog! = Dog()
d.bark()
Применяются IUO, в основном для отложенной инициализации:
class Foo {
var x: Int!
init() {
// I can't setup x at this point :(
x = nil
}
func setup(x newValue: Int) { x = newValue }
func foo() {
// I promise that setupX() will be called before
// I will deal with x as if it was always present
print(x * 2)
}
}
Замечу, что, начиная со Swift 3, IUO - это вовсе не тип, а лишь атрибут переменной, который разрешает неявные преобразования с ней. "Под капотом" всё выглядит как-то так:
let x: Int! = 42
@implicitlyUnwrapped let x: Optional<Int> = .some(42)