You can use if and let together to work with values that might be missing. These values are represented as optionals. An optional value either contains a value or contains nil to indicate that the value is missing. Write a question mark (?) after the type of a value to mark the value as optional.

12 Answers
12

An optional in Swift is a type that can hold either a value or no value. Optionals are written by appending a ? to any type:

var name: String? = "Bertie"

Optionals (along with Generics) are one of the most difficult Swift concepts to understand. Because of how they are written and used, it's easy to get a wrong idea of what they are. Compare the optional above to creating a normal String:

var name: String = "Bertie" // No "?" after String

From the syntax it looks like an optional String is very similar to an ordinary String. It's not. An optional String is not a String with some "optional" setting turned on. It's not a special variety of String. A String and an optional String are completely different types.

Here's the most important thing to know: An optional is a kind of container. An optional String is a container which might contain a String. An optional Int is a container which might contain an Int. Think of an optional as a kind of parcel. Before you open it (or "unwrap" in the language of optionals) you won't know if it contains something or nothing.

You can see how optionals are implemented in the Swift Standard Library by typing "Optional" into any Swift file and ⌘-clicking on it. Here's the important part of the definition:

enum Optional<Wrapped> {
case none
case some(Wrapped)
}

Optional is just an enum which can be one of two cases: .none or .some. If it's .some, there's an associated value which, in the example above, would be the String "Hello". An optional uses Generics to give a type to the associated value. The type of an optional String isn't String, it's Optional, or more precisely Optional<String>.

Everything Swift does with optionals is magic to make reading and writing code more fluent. Unfortunately this obscures the way it actually works. I'll go through some of the tricks later.

Note: I'll be talking about optional variables a lot, but it's fine to create optional constants too. I mark all variables with their type to make it easier to understand type types being created, but you don't have to in your own code.

How to create optionals

To create an optional, append a ? after the type you wish to wrap. Any type can be optional, even your own custom types. You can't have a space between the type and the ?.

Using optionals

var name: String? = "Bob"
name = nil // Set name to nil, the absence of a value
if name != nil {
print("There is a name")
}
if name == nil { // Could also use an "else"
print("Name has no value")
}

This is a little confusing. It implies that an optional is either one thing or another. It's either nil or it's "Bob". This is not true, the optional doesn't transform into something else. Comparing it to nil is a trick to make easier-to-read code. If an optional equals nil, this just means that the enum is currently set to .none.

Only optionals can be nil

If you try to set a non-optional variable to nil, you'll get an error.

Another way of looking at optionals is as a complement to normal Swift variables. They are a counterpart to a variable which is guaranteed to have a value. Swift is a careful language that hates ambiguity. Most variables are define as non-optionals, but sometimes this isn't possible. For example, imagine a view controller which loads an image either from a cache or from the network. It may or may not have that image at the time the view controller is created. There's no way to guarantee the value for the image variable. In this case you would have to make it optional. It starts as nil and when the image is retrieved, the optional gets a value.

Using an optional reveals the programmers intent. Compared to Objective-C, where any object could be nil, Swift needs you to be clear about when a value can be missing and when it's guaranteed to exist.

To use an optional, you "unwrap" it

An optional String cannot be used in place of an actual String. To use the wrapped value inside an optional, you have to unwrap it. The simplest way to unwrap an optional is to add a ! after the optional name. This is called "force unwrapping". It returns the value inside the optional (as the original type) but if the optional is nil, it causes a runtime crash. Before unwrapping you should be sure there's a value.

In this pattern you check that a value is present, then when you are sure it is, you force unwrap it into a temporary constant to use. Because this is such a common thing to do, Swift offers a shortcut using "if let". This is called "optional binding".

This creates a temporary constant (or variable if you replace let with var) whose scope is only within the if's braces. Because having to use a name like "unwrappedMealPreference" or "realMealPreference" is a burden, Swift allows you to reuse the original variable name, creating a temporary one within the bracket scope

Optional binding works by checking to see if the optional equals nil. If it doesn't, it unwraps the optional into the provided constant and executes the block. In Xcode 8.3 and later (Swift 3.1), trying to print an optional like this will cause a useless warning. Use the optional's debugDescription to silence it:

print("\(mealPreference.debugDescription)")

What are optionals for?

Optionals have two use cases:

Things that can fail (I was expecting something but I got nothing)

Things that are nothing now but might be something later (and vice-versa)

Some concrete examples:

A property which can be there or not there, like middleName or spouse in a Person class

A method which can return a value or nothing, like searching for a match in an array

A method which can return either a result or get an error and return nothing, like trying to read a file's contents (which normally returns the file's data) but the file doesn't exist

Delegate properties, which don't always have to be set and are generally set after initialization

For weak properties in classes. The thing they point to can be set to nil at any time

A large resource that might have to be released to reclaim memory

When you need a way to know when a value has been set (data not yet loaded > the data) instead of using a separate dataLoaded Boolean

Optionals don't exist in Objective-C but there is an equivalent concept, returning nil. Methods that can return an object can return nil instead. This is taken to mean "the absence of a valid object" and is often used to say that something went wrong. It only works with Objective-C objects, not with primitives or basic C-types (enums, structs). Objective-C often had specialized types to represent the absence of these values (NSNotFound which is really NSIntegerMax, kCLLocationCoordinate2DInvalid to represent an invalid coordinate, -1 or some negative value are also used). The coder has to know about these special values so they must be documented and learned for each case. If a method can't take nil as a parameter, this has to be documented. In Objective-C, nil was a pointer just as all objects were defined as pointers, but nil pointed to a specific (zero) address. In Swift, nil is a literal which means the absence of a certain type.

Comparing to nil

In more recent versions of Swift you have to use leatherTrim != nil. Why is this? The problem is that a Boolean can be wrapped in an optional. If you have Boolean like this:

var ambiguous: Boolean? = false

it has two kinds of "false", one where there is no value and one where it has a value but the value is false. Swift hates ambiguity so now you must always check an optional against nil.

You might wonder what the point of an optional Boolean is? As with other optionals the .none state could indicate that the value is as-yet unknown. There might be something on the other end of a network call which takes some time to poll. Optional Booleans are also called "Three-Value Booleans"

Swift tricks

Swift uses some tricks to allow optionals to work. Consider these three lines of ordinary looking optional code;

Setting an optional to nil

You can create an optional with no initial value, or create one with the initial value of nil (both have the same outcome).

var name: String?
var name: String? = nil

Allowing optionals to equal nil is enabled by the protocol ExpressibleByNilLiteral (previously named NilLiteralConvertible). The optional is created with Optional's second initializer, public init(nilLiteral: ()). The docs say that you shouldn't use ExpressibleByNilLiteral for anything except optionals, since that would change the meaning of nil in your code, but it's possible to do it:

The same protocol allows you to set an already-created optional to nil. Although it's not recommended, you can use the nil literal initializer directly:

var name: Optional<String> = Optional(nilLiteral: ())

Comparing an optional to nil

Optionals define two special "==" and "!=" operators, which you can see in the Optional definition. The first == allows you to check if any optional is equal to nil. Two different optionals which are set to .none will always be equal if the associated types are the same. When you compare to nil, behind the scenes Swift creates an optional of the same associated type, set to .none then uses that for the comparison.

The second == operator allows you to compare two optionals. Both have to be the same type and that type needs to conform to Equatable (the protocol which allows comparing things with the regular "==" operator). Swift (presumably) unwraps the two values and compares them directly. It also handles the case where one or both of the optionals are .none. Note the distinction between comparing to the nil literal.

Furthermore, it allows you to compare any Equatable type to an optional wrapping that type:

Behind the scenes, Swift wraps the non-optional as an optional before the comparison. It works with literals too (if 23 == numberFromString {)

I said there are two == operators, but there's actually a third which allow you to put nil on the left-hand side of the comparison

if nil == name { ... }

Naming Optionals

There is no Swift convention for naming optional types differently from non-optional types. People avoid adding something to the name to show that it's an optional (like "optionalMiddleName", or "possibleNumberAsString") and let the declaration show that it's an optional type. This gets difficult when you want to name something to hold the value from an optional. The name "middleName" implies that it's a String type, so when you extract the String value from it, you can often end up with names like "actualMiddleName" or "unwrappedMiddleName" or "realMiddleName". Use optional binding and reuse the variable name to get around this.

The official definition

Swift also introduces optional types, which handle the absence of a value. Optionals say either “there is a value, and it equals x” or “there isn’t a value at all”. Optionals are similar to using nil with pointers in Objective-C, but they work for any type, not just classes. Optionals are safer and more expressive than nil pointers in Objective-C and are at the heart of many of Swift’s most powerful features.

Optionals are an example of the fact that Swift is a type safe language. Swift helps you to be clear about the types of values your code can work with. If part of your code expects a String, type safety prevents you from passing it an Int by mistake. This enables you to catch and fix errors as early as possible in the development process.

To finish, here's a poem from 1899 about optionals:

Yesterday upon the stair
I met a man who wasn’t there
He wasn’t there again today
I wish, I wish he’d go awayAntigonish

The sentence "If it's nil, the result of any expression with it is nil as well" is simply wrong. func isNil<T>(t: T?) -> Bool { return t == nil } will return true even if there is a optional value which is nil in the expression.
– return trueApr 24 '15 at 14:32

Incredibly bad code sample. Couldn't you think of something better? Why not simply return x == 5? What is so special about 5?
– AtomoskAug 4 '16 at 4:09

Nope, 2 years ago I couldn't think of something better. Today yes, but does this get the point across? yes. Thanks for the input @Atomosk, it's really helpful.
– John RiselvatoAug 4 '16 at 14:29

You can't have a variable that points to nil in Swift — there are no pointers, and no null pointers. But in an API, you often want to be able to indicate either a specific kind of value, or a lack of value — e.g. does my window have a delegate, and if so, who is it? Optionals are Swift's type-safe, memory-safe way to do this.

In objective C variables with no value were equal to 'nil'(it was also possible to use 'nil' values same as 0 and false), hence it was possible to use variables in conditional statements (Variables having values are same as 'TRUE' and those with no values were equal to 'FALSE').

Swift provides type safety by providing 'optional value'. i.e. It prevents errors formed from assigning variables of different types.

So in Swift, only booleans can be provided on conditional statements.

var hw = "Hello World"

Here, even-though 'hw' is a string, it can't be used in an if statement like in objective C.

nil is just syntactic sugar for the enum constant OptionalValue<T>.None (where T is the type appropriate to the context where you're using nil). ? is a shortcut for OptionalValue<T>.Some(T).
– ricksterJun 2 '14 at 21:47

When i started to learn Swift it was very difficult to realize why optional.

Lets think in this way.
Let consider a class Person which has two property name and company.

class Person: NSObject {
var name : String //Person must have a value so its no marked as optional
var companyName : String? ///Company is optional as a person can be unemployed that is nil value is possible
init(name:String,company:String?) {
self.name = name
self.companyName = company
}
}

Now Lets talk about why we use optional?.
Lets consider a situation where we want to add Inc after company name like apple will be apple Inc. We need to append Inc after company name and print.

print(tom.companyName+" Inc") ///Error saying optional is not unwrapped.
print(tom.companyName!+" Inc") ///Error Gone..we have forcefully unwrap it which is wrong approach..Will look in Next line
print(bob.companyName!+" Inc") ///Crash!!!because bob has no company and nil can be unwrapped.

Now lets study why optional takes into place.

if let companyString:String = bob.companyName{///Compiler safely unwrap company if not nil.If nil,no unwrap.
print(companyString+" Inc") //Will never executed and no crash!!!
}

Lets replace bob with tom

if let companyString:String = tom.companyName{///Compiler safely unwrap company if not nil.If nil,no unwrap.
print(companyString+" Inc") //Will never executed and no crash!!!
}

And Congratulation! we have properly deal with optional?

So the realization points are

We will mark a variable as optional if its possible to be nil

If we want to use this variable somewhere in code compiler will
remind you that we need to check if we have proper deal with that variable
if it contain nil.

Optional chaining is a process for querying and calling properties, methods, and subscripts on an optional that might currently be nil. If the optional contains a value, the property, method, or subscript call succeeds; if the optional is nil, the property, method, or subscript call returns nil. Multiple queries can be chained together, and the entire chain fails gracefully if any link in the chain is nil.

? (Optional) indicates your variable may contain a nil value while ! (unwrapper) indicates your variable must have a memory (or value) when it is used (tried to get a value from it) at runtime.

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.

To reflect the fact that optional chaining can be called on a nil value, the result of an optional chaining call is always an optional value, even if the property, method, or subscript you are querying returns a nonoptional value. You can use this optional return value to check whether the optional chaining call was successful (the returned optional contains a value), or did not succeed due to a nil value in the chain (the returned optional value is nil).

Specifically, the result of an optional chaining call is of the same type as the expected return value, but wrapped in an optional. A property that normally returns an Int will return an Int? when accessed through optional chaining.

This declaration creates a variable named middleName of type String. The question mark (?) after the String variable type indicates that the middleName variable can contain a value that can either be a String or nil. Anyone looking at this code immediately knows that middleName can be nil. It's self-documenting!

If you don't specify an initial value for an optional constant or variable (as shown above) the value is automatically set to nil for you. If you prefer, you can explicitly set the initial value to nil:

Thank you for your interest in this question.
Because it has attracted low-quality or spam answers that had to be removed, posting an answer now requires 10 reputation on this site (the association bonus does not count).