iosswiftgenericsswift-protocols

Usage of protocols as array types and function parameters in Swift


I want to create a class that can store objects conforming to a certain protocol. The objects should be stored in a typed array. According to the Swift documentation protocols can be used as types: 

Because it is a type, you can use a protocol in many places where other types are allowed, including:

  • As a parameter type or return type in a function, method, or initializer
  • As the type of a constant, variable, or property
  • As the type of items in an array, dictionary, or other container

However the following generates compiler errors:

Protocol 'SomeProtocol' can only be used as a generic constraint because it has Self or associated type requirements

How are you supposed to solve this:

protocol SomeProtocol: Equatable {
    func bla()
}

class SomeClass {
    
    var protocols = [SomeProtocol]()
    
    func addElement(element: SomeProtocol) {
        self.protocols.append(element)
    }
    
    func removeElement(element: SomeProtocol) {
        if let index = find(self.protocols, element) {
            self.protocols.removeAtIndex(index)
        }
    }
}

Solution

  • This can now be solved using any, released with Swift 5.6 and Xcode 13.3 in March 2022.

    SE-0335: Introduce existential any

    protocol SomeProtocol: Equatable {
        func bla()
    }
    
    class SomeClass {
        var protocols = [any SomeProtocol]()
        
        func addElement(element: any SomeProtocol) {
            protocols.append(element)
        }
        
        func removeElement(element: any SomeProtocol) {
            if let index = find(protocols, element) {
                protocols.remove(at: index)
            }
        }
    }