import Foundation
// Associated types allow for use of 'generic' placeholders in protocol definitions
// These associated types are defined later when the protocol is implemented
protocol Item { }
struct RandomItem: Item { }
protocol ItemStorage {
associatedtype ItemType
mutating func addItem(number: ItemType)
}
/* To Show ability to discern between protocols */
protocol RemovableStorage: ItemStorage { }
struct Cart: RemovableStorage {
var items = [Item]()
init(initialItem: Item? = nil) {
if let initialItem = initialItem {
items.append(initialItem)
}
}
mutating func addItem(item: Item) {
items.append(item)
}
}
var newCart = Cart(initialItem: RandomItem())
newCart.addItem(RandomItem())
assert(newCart.items.count == 2)
// Associated Types with generics
struct GenericStorage<T>: ItemStorage {
var items: [T]
init(initialItem: T? = nil) {
if let initialItem = initialItem {
items = [initialItem]
} else {
items = [T]()
}
}
mutating func addItem(item: T) {
items.append(item)
}
}
var basket = GenericStorage<Item>(initialItem: RandomItem())
assert(basket.items.count == 1)
/* Extension can be confined to specific types */
extension ItemStorage where Self: RemovableStorage {
func printMessage() {
print("I'm a Cart with removable storage")
}
}
newCart.printMessage()
/* Extensions can also check that sub elements conform to other protocols */
extension CollectionType where Generator.Element: Comparable { }