Usage of protocols as array types and function parameters in swift

snod picture snod · Jul 22, 2014 · Viewed 28.7k times · Source

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)
        }
    }
}

Answer

DarkDust picture DarkDust · Jul 22, 2014

You've hit a variant of a problem with protocols in Swift for which no good solution exists yet.

See also Extending Array to check if it is sorted in Swift?, it contains suggestions on how to work around it that may be suitable for your specific problem (your question is very generic, maybe you can find a workaround using these answers).