June 03, 2014
Swift has optional types. Optional types can have a value or no value (like a pointer can have a value or nil). The intention is to replace nil checks everywhere with concise syntax and type safety. An optional type is declared by tossing a ? at the end of the type like so:
var pants:String? = "Pants"
The non-optional equivalent is:
var pants:String = "Pants"
So why is this an improvement over Objective-C?
This post was written using Swift 1.0.
Here’s a check for whether pants are present in Objective-C:
NSString *pants = @"Pants";
if (pants != nil)
{
NSLog(@"Haz pants");
[pants doStuffWithPants];
}
else
{
NSLog(@"No pants!");
}
If you forgot to check for nil before calling [pants doStuffWithPants], you’d have a crash :(
We could be literal and do the exact same thing in Swift with Optional Pants:
var pants:String? = "Pants"
if (pants)
{
println("Haz pants")
pants.doStuffWithPants()
}
else
{
println("No pants")
}
In Swift with optional pants you can’t compile a call to pants.doStuffWithPants() without the nil check (explicitly or using the ? syntax discussed at the bottom of this post).
But if we don’t make Pants Optional, the nil check won’t even compile
var pants:String = "Pants"
if (pants)
// error: type 'String' does not conform to protocol 'LogicValue'
In Objective-C pants are always optional. In Swift pants are only optional if you explicitly say they’re optional.
In Swift, there’s a cleaner way to handle optional types (though it doesn’t include handling the nil case separately, so no “No pants” log statement here). Using ? after the variable checks for nil and short-circuits the operation if the var is nil. Using ! after the variable forces the evaluation of the whole operation, which crashes if the optional var is nil:
var pants:String? = "Pants"
pants = nil
pants?.doStuffWithPants() // doStuffWithPants() only called if pants != nil
pants!.doStuffWithPants() // will crash if pants == nil
// since ! forces doStuffWithPants() to be called
P.S. That Objective-C already feels more laborious to type. I had to go back and add the @ and ;’s that I skipped. At least the syntax of Swift seems easy to pick up.