Search code examples
swiftprotocolsswift4swift-protocols

Protocol extension to be applied to several types


I have a protocol, for instance:

protocol P {
    func foo()
}

It is possible to make default implementation for some type:

extension P where Self == Int {
    func foo() {
        // do something
    }
}

But how to have same default implementation for several types? Like this:

extension P where Self == Int or Self == Float {
    func foo() {
        // do something
    }
}

Solution

  • You can unite the types with another protocol (for example HasDefaultFoo). This allows the types to decide when adopting the protocol if they want the default implementation.

    protocol P {
        func foo()
    }
    
    protocol HasDefaultFoo {
        func foo()
    }
    
    extension Int: P, HasDefaultFoo { }
    extension Float: P, HasDefaultFoo { }
    
    extension P where Self: HasDefaultFoo {
        func foo() {
            print(self)
        }
    }
    
    extension Double: P {
        func foo() {
            print("I provide my own foo()")
        }
    }
    

    Example:

    5.foo()
    (5.5 as Float).foo()
    5.5.foo()
    

    Output:

    5
    5.5
    I provide my own foo()