Downcasting optionals in Swift: as? Type, or as! Type?

sdduursma picture sdduursma · Sep 7, 2014 · Viewed 40.1k times · Source

Given the following in Swift:

var optionalString: String?
let dict = NSDictionary()

What is the practical difference between the following two statements:

optionalString = dict.objectForKey("SomeKey") as? String

vs

optionalString = dict.objectForKey("SomeKey") as! String?

Answer

vacawama picture vacawama · Sep 7, 2014

The practical difference is this:

var optionalString = dict["SomeKey"] as? String

optionalString will be a variable of type String?. If the underlying type is something other than a String this will harmlessly just assign nil to the optional.

var optionalString = dict["SomeKey"] as! String?

This says, I know this thing is a String?. This too will result in optionalString being of type String?, but it will crash if the underlying type is something else.

The first style is then used with if let to safely unwrap the optional:

if let string = dict["SomeKey"] as? String {
    // If I get here, I know that "SomeKey" is a valid key in the dictionary, I correctly
    // identified the type as String, and the value is now unwrapped and ready to use.  In
    // this case "string" has the type "String".
    print(string)
}