3

I have an implicitly unwrapped optional with value nil.

Why does it print nil and not crash?

var x : Int!
print(x) // nil
pkamb
  • 33,281
  • 23
  • 160
  • 191
  • 1
    it should... if thats what you have done... show your code – Scriptable Apr 30 '19 at 08:25
  • 1
    Compare e.g. https://stackoverflow.com/questions/49559821/explicitly-unwrapping-optional-nil-does-not-cause-crash. – An IUO is only force-unwrapped if required by the type checker, otherwise it behaves like a regular optional. – Martin R Apr 30 '19 at 08:29
  • `var x: Int? print(x!)` – jack jay Apr 30 '19 at 08:31
  • could you clarify – Haitham Gado Apr 30 '19 at 08:33
  • because when you use ! for unwrapped you tell Xcode I'm sure I fill it before I wanna use it – mohsen Apr 30 '19 at 08:46
  • Note that your code produces the warning "Expression implicitly coerced from 'Int?' to 'Any'", and [this warning will soon be improved](https://github.com/apple/swift/pull/23617) to "coercion of implicitly unwrappable value of type 'Int?' to 'Any' does not unwrap optional" for IUOs. – Hamish Apr 30 '19 at 10:21

2 Answers2

3

That does not crash because print accepts Any as the first parameter. Are implicitly unwrapped optionals a kind of Any? Yes they are! Anything is Any. There is no need to unwrap the optional. An implicitly unwrapped optional can be used in a place where Any is expected without unwrapping the optional.

That could potentially be confusing because now you have something with type Any, which doesn't look like it's optional, but it is an optional under the hood. To avoid this, Swift will output a warning telling you that you are implicitly coercing whatever optional type to Any.

You need to use ! to force unwrap it here:

print(x!)
Sweeper
  • 213,210
  • 22
  • 193
  • 313
0

The reason why it's not crashing is because you are not force-unwrapping it in print(x). It will only crash one you try to force-unwrap it like print(x!)

IUO(Implicitly Unwrapped Optionals) are just special type of Optionals which will be automatically unwrapped one you use it inside chaining (say optional chaining), otherwise they remain Optionals.

Consider an example:

var implicitlyUO: Int!
implictlyUO = 4

print(implicitlyUO) // prints Optional(4)
print(implicitlyUO.advanced(by: 3)) // prints 7

implicitlyUO = nil

print(implicitlyUO) // prints nil
print(implicitlyUO.advanced(by: 3)) // Here it will crash as now it will be unwrapped and found it nil

var someNilValue:Int?
someNilValue = 4

print(someNilValue) // prints Optional(4)
print(someNilValue?.advanced(by: 3)) // prints Optional(7)

someNilValue = nil

print(someNilValue) // prints nil
print(someNilValue?.advanced(by: 3)) // prints nil
print(someNilValue!.advanced(by: 3)) /* Will crash here as we are force unwrapping nil which is the same case as implicitlyUO */

The only advantage you get with IUO is that you don't need ! (or explicitly unwrapping) in your code unnecessarily but you need to make sure that it is not nil.

Shubham Bakshi
  • 552
  • 3
  • 10