An elegant way to update variables without unwrapping optionals using custom Swift operators

In Swift, you may want to update the value of a variable only if it is not nil. This can be cumbersome to do with regular assignment syntax, as you have to first unwrap the optional value and check if it is not nil before performing the assignment.

let originalStory: Story? = ...

if let originalStory = originalStory {
    story.basedOn = originalStory
}

By creating a custom operator, you can easily and elegantly perform this type of conditional assignment in a single step. Creating a custom operator ?= can help make your code more concise and maintainable, here is the code for the operator:

infix operator ?= : AssignmentPrecedence

func ?= <T>(lhs: inout T, rhs: T?) {
    if let value = rhs {
        lhs = value
    }
}

This operator is using generic and can be used with variables of any type, so long that the left and right operands are of the same type.

You could use this operator to update the value of a variable only if the right operand is not nil, like this:

var x = 1
x ?= nil // x remains 1
x ?= 2 // x is now 2

This operator uses the AssignmentPrecedence precedence group, which means that it will have lower precedence than the assignment operator (=).

One of the most useful uses I find in this custom operator is when updating the content of a dictionary if and only the variables are not nil. For instance in this code where both game.clef and game.mode are optional and could be nil:

var properties: [String: Any] = [:]
if let clef = game.clef {
    properties["clef"] = clef
}
if let mode = game.mode {
    properties["mode"] = mode
}

becomes:

var properties: [String: Any] = [:]
properties["clef"] ?= game.clef
properties["mode"] ?= game.mode

Leave a Reply

Your email address will not be published. Required fields are marked *