Generics - RaduG/swift_learning GitHub Wiki
struct Queue<T> {
var items = [T]()
mutating func push(_ element: T) {
items.append(element)
}
mutating func pop() -> T {
return items.removeFirst()
}
}
var q = Queue<String>()
q.push("abc")
q.push("def")
print(q.pop())
print(q.pop())
Instead of declaring the extension as having a generic type, the generic type in the original class's declaration is available in the extension automatically.
extension Queue {
func toList() -> [T] {
return items
}
}
var q = Queue<String>()
q.push("abc")
q.push("def")
print(q.toList())
func someFunc<T: SoneType, U: SomeProtocol & SomeOtherProtocol>(_ x: T, _ y: U) {}
protocol Container {
associatedtype Item
var size: Int { get }
mutating func push(_ item: Item)
mutating func pop() -> Item
}
struct IntQueue: Container {
typealias Item = Int
var items = [Int]()
var size: Int {
items.count
}
mutating func push(_ item: Int) {
items.append(item)
}
mutating func pop() -> Int {
return items.removeFirst()
}
}
struct Queue<Item> {
var items = [Item]()
var size: Int {
items.count
}
mutating func push(_ element: Item) {
items.append(element)
}
mutating func pop() -> Item {
return items.removeFirst()
}
}
Associated types can also have constraints:
associatedtype Item: Equatable
protocol SuffixableContainer: Container {
associatedtype Suffix: SuffixableContainer where Suffix.Item == Item
func suffix(_ size: Int) -> Suffix
}
extension Queue where Item == Int {
func average() -> Int {
var sum: Int = 0
for index in 0..<size {
sum += self[index]
}
return sum / size
}
}
var queue = Queue<Int>()
queue.push(12)
queue.push(13)
print(queue.average())
Where clauses can also be written on a method-by-method basis:
extension Queue {
func average() -> Int where Item == Int {
var sum: Int = 0
for index in 0..<size {
sum += items[index]
}
return sum / size
}
}
Associated types can also have where clauses:
protocol Container {
associatedtype Item
mutating func append(_ item: Item)
var count: Int { get }
subscript(i: Int) -> Item { get }
associatedtype Iterator: IteratorProtocol where Iterator.Element == Item
func makeIterator() -> Iterator
}
extension Container {
subscript<Indices: Sequence>(indices: Indices) -> [Item]
where Indices.Iterator.Element == Int {
var result = [Item]()
for index in indices {
result.append(self[index])
}
return result
}
}