In addition to generic functions, Swift enables you to define your own generic types. These are custom classes, structures,and enumerations that can work with any type, in a similar way to Array
and Dictionary
.
This section shows you how to write a generic collection type called Stack
. A stack is an ordered set of values, similar to an array, but with a more restricted set of operations than Swift's Array
type. An array allows new items to be inserted and removed at any location in the array. An stack, however, allows new items to be appended only to the end of the collection (known as pushing a new value on to the stack). Similarly, a stack allows items to be removed only from the end of the collection (known as poping a value off the stack).
The illustraction below shows the push/pop behavior for a stack:
1、There are currently three values on the stack.
2、A fourth value if "pushed" on to the top of the stack.
3、The stack now holds four values, with the most recent one at the top.
4、The top item in the stack is removed, or "poped".
5、After poping a value, the stack once again holds three values.
Here's how to write a non-generic version of a stack, in this case for a stack of Int values:
struct IntStack {
var items = [Int]()
mutating func push(item: Int) {
items.append(item)
}
mutating func pop()->Int {
return items.removeLast()
}
}
This structure uses an Array
property called items
to store the values in the stack. Stack
provides two methods, push
and pop
, to push and pop values on and off the stack. These methods are marked as mutating
, because they need to modify (or mutate) the structure's items
array.
The IntStack
type shown above can only be used with Int
values, however. It would be much more useful to define a generic Stack
class, that can manage a stack of any type of value.
Here's a generic version of the same code:
struct Stack<T> {
var items = T
mutating func push(item: T) {
items.append(item)
}
mutating func pop()->T {
return items.removeLast()
}
}
Note how the generic version of Stack
is essentially the same as the non-generic version, but with a placeholder type parameter called T
instead of an actual type of Int
. This type parameter is written within a pair of angle brackets (<T>
) immediately after the structure's name.
T
defines a placeholder name for "some type T
" to be provided later on. This future type can be referred to as "T
" anywhere within the structure's definition. In this case, T
is used as a placeholder in three places:
- To create a property called
items
, which is initialized with an empty array of value of typeT
- To specify that the
push(_:)
method has a single parameter calleditem
, which must be of typeT
- To specify that the value returned by the
pop()
method will be a value of typeT
Because it is a generic type, Stack
can be used to create a stack of any valid type in Swift, in a similar manner to Array
and Dictionary
.
You create a new Stack
instance by writing the type to be stored in the stack within angle brackets. For example, to create a new stack of strings, you write Stack<String>():
var stackOfStrings = Stack<String>()
stackOfStrings.push("uno")
stackOfStrings.push("dos")
stackOfStrings.push("tres")
stackOfStrings.push("cuatro")
// the stack now caontains 4 strings
Here's how stackOfStrings
looks after pushing these four values on to the stack:
Popping a value from the stack returns and removes the top value, "cuatro
":
let fromTheTop = stackOfString.pop()
// fromThePop is equal to "cuatro", and the stack now contains 3 strings.
Here's how the stack looks after popping its top value: