I have the below code and it works fine, but I was expecting the line print(john.residence!.numberOfRooms)
to crash, as my numberOfRooms
variable has nil
value and I am not using forced wrapping when passing its value as argument to print()
. Can anyone please explain why is this not triggering a runtime error and printing nil
safely instead?
class Person {
var residence: Residence?
}
class Residence {
var numberOfRooms: Int?
}
let john = Person()
john.residence = Residence()
print(john.residence!.numberOfRooms)
What you are doing is called Optional Chaining. Both Optional Chaining and Forced Unwrapping do the same thing, but:
The main difference is that optional chaining fails gracefully when the optional is nil, whereas forced unwrapping triggers a runtime error when the optional is nil.
“The Swift Programming Language (Swift 2.2).” iBooks. https://itun.es/br/jEUH0.l
You're force unwrapping the .residence
property, which is not nil
: It contains a Residence
instance, which has its .numberOfRooms
property set as nil
because it wasn't initialized. Since you're not force unwrapping it, no errors are given, due to optional chaining. Try force unwrapping the .numberOfRooms
property instead to get an error:
print(john.residence!.numberOfRooms!)
Or, you can remove the following line to set .residence
as nil
:
john.residence = Residence()
This way john
has no .residence
, so trying to force unwrap it will make the Swift compiler throw a runtime error.