Published on

Foundational Swift Types

Authors
Swift Generics Hero Image

In the Swift programming language, nearly everything is based on a named type or compound type. Named types can be assigned names when created. These include classes, structures, enumerations, and protocols. Instances of user-defined named types carry the name of the given type. For example, a class named MyClass will have the type MyClass. Swift also includes many standard named types for arrays, dictionaries and optional values.

This is a another post in a series intended as a personal growth exercise. As I learn and digest new things, I want to write about them to solidify my understanding.

Feynman →

Compound types are types without a specific name. A compound type may contain other named and compound types. For example, the compound tuple type (Int, (Int, Int)) contains two inner types. The first is the named Int type, the second is a compount type of (Int, Int).

Properties are either stored, or computed. A stored property has a fixed value. On the other hand, a computed property is calculated every time it is are accessed. There are also simple observers on properties that listen to changes via callbacks. These observers are willSet and didSet.

This was very difficult for me to wrap my head around in my early Swift learning days.

Value types vs Reference types

When a piece of data is saved to disk, it is saved in a container. Imagine each container having a label on the outside. Value types refer to the actual data inside the container. Reference types refer to the label, or memory address on the container.

class SimpleClass {
    var name = ""
}

struct SimpleStruct {
    var name = ""
}

// Memory address is constant but data is variable
let simpleClass = SimpleClass()
simpleClass.name = "wayne" // OK

// Data is constant but address is variable
let simpleStruct = SimpleStruct()
simpleStruct.name = "wayne" // Compiler error

So here we have a constant (let) class instance with a constant memory address, but its data is variable and can change at any time. This was a huge eye opener for me to learn early on.

However, a constant (let) structure instance has constant data, but a variable memory address. It will throw a compiler error every time the constant structure is changed.

Convention tells us to use struct primarily, but should opt for class when our code is designed for instances, as well as interfacing with legacy Objective-C code.

Computed Properties — Getters & Setters

Computed properties have special functions for getting and setting of property values. It's value is determined by the getter function every time it's accessed, instead of some stored property with a specific value.

Getter functions can retrieve data from storage and setter functions can assign the data to storage directly.

var randomInteger: Int {
  get {
    return 100 * Int.random(in: 0...10)
  }
}

Setter functions are optional in computed properties. When no setter function is defined, it's treated as a normal stored, read-only property.

Summary

  • Reference type instance points to the memory address, not the data
  • Value type instance points to the data but not the memory address
  • Getter and setter functions are called when computed properties are accessed or modified.

Resources: