Pointers in Swift

Swift supports pointers, allowing you to pass references to values and records within your program.

import Foundation

// We'll show how pointers work in contrast to values with
// 2 functions: `zeroval` and `zeroptr`. `zeroval` has an
// `Int` parameter, so arguments will be passed to it by
// value. `zeroval` will get a copy of `ival` distinct
// from the one in the calling function.
func zeroval(_ ival: Int) {
    var localIval = ival
    localIval = 0
}

// `zeroptr` in contrast has an `UnsafeMutablePointer<Int>` parameter, 
// meaning that it takes an Int pointer. The `iptr.pointee` code in the
// function body then dereferences the pointer from its
// memory address to the current value at that address.
// Assigning a value to a dereferenced pointer changes the
// value at the referenced address.
func zeroptr(_ iptr: UnsafeMutablePointer<Int>) {
    iptr.pointee = 0
}

func main() {
    var i = 1
    print("initial:", i)

    zeroval(i)
    print("zeroval:", i)

    // The `&i` syntax gives the memory address of `i`,
    // i.e. a pointer to `i`.
    withUnsafeMutablePointer(to: &i) { pointer in
        zeroptr(pointer)
    }
    print("zeroptr:", i)

    // Pointers can be printed too.
    print("pointer:", withUnsafePointer(to: &i) { String(format: "%p", $0) })
}

main()

zeroval doesn’t change the i in main, but zeroptr does because it has a reference to the memory address for that variable.

$ swift pointers.swift
initial: 1
zeroval: 1
zeroptr: 0
pointer: 0x16fdff298

In Swift, direct pointer manipulation is considered unsafe and is generally discouraged. Instead, Swift provides safer alternatives like inout parameters for most use cases where you might use pointers in other languages. However, for the purpose of this example, we’ve used UnsafeMutablePointer to demonstrate the concept of pointers.