Swift Generic Types
A generic type is a type that holds values of a placeholder type. Each value made from the type fixes the placeholder to one real type.
A box for any type
The Box struct stores one value of the placeholder type T. One box holds the number 42 and another box holds the word hello.
struct Box<T> {
var value: T
}
let numberBox = Box(value: 42)
let wordBox = Box(value: "hello")
print(numberBox.value)
print(wordBox.value)A stack of numbers
The Stack struct stores its elements in an array of the placeholder type. Pushing 10 and then 20 makes 20 the top element, so popping prints 20 and one element remains.
struct Stack<Element> {
var items: [Element] = []
mutating func push(_ item: Element) {
items.append(item)
}
mutating func pop() -> Element? {
return items.popLast()
}
}
var stack = Stack<Int>()
stack.push(10)
stack.push(20)
if let top = stack.pop() {
print(top)
}
print(stack.items.count)A generic enum with two cases
The Wrapper enum holds a value in its some case and holds nothing in its none case. The filled wrapper prints its word, and the empty wrapper prints a fixed line.
enum Wrapper<T> {
case some(T)
case none
}
let filled = Wrapper.some("ready")
let empty = Wrapper<String>.none
switch filled {
case .some(let value):
print(value)
case .none:
print("nothing")
}
switch empty {
case .some(let value):
print(value)
case .none:
print("nothing")
}Example
struct Stack<Element> {
var items: [Element] = []
mutating func push(_ item: Element) {
items.append(item)
}
mutating func pop() -> Element? {
return items.popLast()
}
}
var stack = Stack<String>()
stack.push("first")
stack.push("second")
if let top = stack.pop() {
print(top)
}
print(stack.items.count)Key points
- The placeholder sits inside angle brackets after the type name in its declaration.
- Inside the type, stored properties and methods use the placeholder wherever the held type belongs.
- A value made as Box<Int> holds Int values, and a value made as Box<String> holds String values.
- One generic type can serve many held types without a separate declaration for each.
- The compiler keeps the held types separate, so a box of numbers never mixes with a box of words.
In this example, a Stack is made with String as its element type. Pushing first and then second places second on top, so the pop prints second. One element remains, so the count print shows 1.
Note
The placeholder is chosen when a value is made, and it stays fixed for the whole life of that value.
Try it Yourself
Edit the code, then press Run.
Running is simulated
Exercise
A program declares struct Box<T> and makes a value as Box<Int>. What type does that box hold?