Search code examples
swiftswift2

Associated Types in Swift


What are associated types in swift programming language? What are they used for?

As per swift programming language book:

When defining a protocol, it is sometimes useful to declare one or more associated types as part of the protocol’s definition. An associated type gives a placeholder name (or alias) to a type that is used as part of the protocol. The actual type to use for that associated type is not specified until the protocol is adopted. Associated types are specified with the typealias keyword.

The above text is not very clear to me. It would help a lot if you can explain associated types with an example.

Also, why is it useful to declare an associated type as part of a protocol definition?


Solution

  • You have a protocol that defines methods and perhaps properties that an implementing type must provide. Some of those methods/properties use or return objects of a different type to the type implementing the protocol. So, for instance, if you have a protocol that defines certain types of collections of objects, you might define an associated type which defines the elements of the collection.

    So let's say I want a protocol to define a Stack, but a Stack of what? It doesn't matter, I just use an associated type to act as a place holder.

    protocol Stack
    {
        // typealias Element - Swift 1
        associatedtype Element // Swift 2+
        func push(x: Element)
        func pop() -> Element?
    }
    

    In the above Element is the type of whatever objects are in the stack. When I implement the stack, I use typealias to specify the concrete type of the stack elements.

    class StackOfInt: Stack
    {
        typealias Element = Int // Not strictly necessary, can be inferred
        var ints: [Int] = []
    
        func push(x: Int)
        {
            ints.append(x)
        }
    
        func pop() -> Int?
        {
            var ret: Int?
            if ints.count > 0
            {
                ret = ints.last
                ints.removeLast()
            }
            return ret
        }
    }
    

    In the above, I have defined a class that implements Stack and says that, for this class, Element is actually Int. Frequently, though, people leave out the typealias because the concrete type of Element can be inferred from the method implementations. e.g. the compiler can look at the implementation of push() and realise from the type of the parameter that Element == Int in this case.