In Swift when you declare a variable with a type (without explicitly making it an Optional), it must have a value before it is used. It will not default to nil and cannot hold nil without explicitly making it an Optional.
So, the following code will give an error:
var petName: String
The compiler will say that the variable name is being used before it is initialized. In this case, the variable petName holds a value of String type and after the initialization it cannot be assigned a nil value.
So, the following code also will give an error:
var petName = “Sparky”
petName = nil
Since the petName is assigned a string value (Sparky), Swift will use its built-in Type Inference and make the variable petName of type String. Since it is initialized and contains a value, The print function will print Sparky without any problem.
The problem happens when nil is assigned to petName. Since this variable is of type String, it is always expected to have a String value in it. Compiler errors saying, nil cannot be assigned to type ‘String’.
This is where Optionals come into play.
The concept behind Optionals in Swift is that, they can hold one of the two values:
- No value — non-existence of a value
- Some value of the type specified
Swift forces you to explicitly say that a given variable can contain a no value. If you have not explicitly mentioned it (by declaring the variable as optional), then it just cannot NOT have a value. This makes the code safe because you can be confident that any operation you do on this variable can expect some value of that specific type to be available in that variable. You don’t need to constantly test for nil on this variable.
In Swift nil denotes the absence of value. And it can be used on any type. Let’s see how an optional is declared in the section below.
In order to make a variable (or constant) an Optional, you will put a ? (question mark) next to the type. For example:
var roundScore: Int?
roundScore = 100
roundScore = nil
// prints nil
roundScore = 200
// prints Optional(200)
Here, you are saying that the variable roundScore is an Optional Integer. That means, it is OK for roundScore to not have a value (i.e. nil) or, if it is going to have some value, it must be an Integer.
So, the type of roundScore is Optional<Int>, not Int. In fact, when you print an optional variable as it is, it will print Optional(value). For example, in the above code, it will print Optional(200) if the Int value inside 200.
You cannot use this value where Int is used without unwrapping (we will discuss this in the next articles). We will also discuss how to safely unwrap an Optional by checking whether there is some value in it first.
You can also make constants Optionals. The constants in Swift are declared with keyword let. Since a constant can be assigned a value only once, there will be an error if you try to change that value at a later point. That is not because it is Optional, but because it is because it is immutable.
let cityName: String?
cityName = "San Francisco"
// Problem here
cityName = nil
In the code above, first time you can assign a city name string to the constant (it can also be a nil). However, you cannot change it after you have assigned it once (because a constant is immutable, whether it’s an Optional or not).
Next we will look at how Swift actually implemented Optionals. After that we will look at forced and implicit unwrapping of Optionals.