Are Pants Optional in Swift?
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.