What Does The Question Mark Mean In Swift

If you’re new to Swift, you’ll see a lot of question marks. Not all other languages have this feature, but its a built-in safety feature of Swift.

A question mark ? means the value is optional. Optionals could contain a value or it could be nil.

What Are Optionals?

Optionals are a built-in safety feature of Swift. Any type of variable can be an optional. To define an optional variable, simply put a ? after its type.

var optionalString: String?
var optionalInt: Int?
var optionalBool: Bool?

Optionals are important because they let developers know that this variable might be nil and that they should unwrap it before using it. You might be tempted to force unwrap it with a ! but this is bad practice and circumvents the safety features of Swift.

By safely unwrapping optionals, developers can clearly define the code behavior when the variable is nil and when it contains a value.

How To Safely Unwrap Optionals?

You could do it by checking for nil, like in many other languages. For example:

var greeting: String?
if greeting != nil {
    print(greeting! + " friend")
}

However, this still involves force unwrapping and using the ! operator. A more Swift approach would be to use optional binding.

Optional Binding

Optional binding checks first if the optional has a value and if it does, assigns it to a non-optional constant. This pattern is used quite often in Swift development.

Here’s an example:

var greeting: String?
if let unwrappedGreeting = greeting {
    print(unwrappedGreeting + " friend")
} else {
    print("greeting has no value!")
}

Notice in this pattern we don’t use any force unwraps (!). You can also chain this together with multiple optionals:

var greeting: String?
var friendsName: String?
if let unwrappedGreeting = greeting, let unwrappedFriendsName = friendsName {
    print(unwrappedGreeting + " " + unwrappedFriendsName)
} else {
    print("greeting or friend has no value!")
}

This above code will print greeting or friend has no value!. However, if we assign values to both of those valuables like so:

var greeting: String? = "Hey"
var friendsName: String? = "Eddie"
if let unwrappedGreeting = greeting, let unwrappedFriendsName = friendsName {
    print(unwrappedGreeting + " " + unwrappedFriendsName)
} else {
    print("greeting or friend has no value!")
}

It will print:

Hey Eddie

Guard Statements

What if you want to use this variable outside of an if statement? Do you have to continually wrap it in if statements? Nope! There’s a better solution, it’s called a guard statement.

Guard statements define a condition for the code to continue, otherwise it must return. You can use this in combination with optional binding like so:

printGreeting()

func printGreeting() {
    var greeting: String?
    var friendsName: String?

    guard let unwrappedGreeting = greeting, let unwrappedFriendsName = friendsName else {
        print("greeting or friend has no value!")
        return
    }

    print(unwrappedGreeting + " " + unwrappedFriendsName)
}

I use guard statements quite frequently when I’m writing Swift code.

Nil Coalescing Operator

The nil coalescing operator is shorthand if statement. It lets you define a default value if the optional contains nil.

var greeting: String?
var friendsName: String?

print((greeting ?? "Hi") + " " + (friendsName ?? "friend"))

In our above example, if no value is provided for greeting or friend, it will print the “Hi friend”.

If you liked this post and want to learn more, check out The Complete iOS Developer Bootcamp. Speed up your learning curve - hundreds of students have already joined. Thanks for reading!

Eddy Chung

I teach iOS development on ZeroToAppStore.com.

Similar Posts