What's the difference between a stored and a computed property? And what is the right syntax?

During my day to day work I came across these questions a few times already and every time I forget the answer. I am finally writing it down for you and for me to remember.

The first difference is that stored properties store constant and variable values as part of an instance, whereas computed properties calculate (rather than store) a value.

Stored properties

A stored property is a property whose initalizer is called only once. It can be immutable if declared as a let or later assigned if you declare it as a var.

It can also be lazy[1] and in that case you can reference self in there! They can only be used in classes and structs.

class Rectangle {
    let height: Int = 15
    let width: Int = 20

    // initialised via closure and lazy
    lazy var perimeter: Int = {
        return height * 2 + width * 2   
    }()
}

This class contains all stored properties. Every time you use the perimeter property, the returned value is the same and, since we declared it as lazy, the initialisation only happens the first time you use it.

Computed properties

A computed property initializer is called every time you reference the property. You can provide a custom getter and setter for it.

var width: Int {
    get {
        return 10
    }
    set {
        width = newValue
    }
}

If you don't specify the setter, it will be read-only and you can omit the keyword get and the braces. It can't be declared as lazy and can't be declared as a let. You can use computed properties in classes, structs and enumerations.

class Rectangle {
    var height: Int = 15
    var width: Int = 20

    var perimeter: Int {
        return height * 2 + width * 2
    }
}

In this example the perimeter property is calculated every time you use it and its result could be different if height or width have changed.

[1] A lazy variable gets calculated the first time that it is actually needed. The advantage is that the second time that you use the variable the value returned is already stored, but be careful the fact that they are not initialised atomically makes them not thread safe.

Conclusion

If you want to read more about properties in Swift here is the link to Apple documentation.

Hope this was helpful!