Search code examples
iosarraysswiftprotocolsgenerics

Swift: Array property with elements conforming to a class and multiple protocols simultaneously


In Objective-C there is a way to declare a variable conforming to a class and a set of protocols like this:

BaseClass<Protocol1, Protocol2> *variable = ...

In Swift I would like to declare an array (actually as a property of a class) with elements of a type defined by this pattern.

In this question there is a solution for describing the type of a standalone property by making the class generic and constraining the type accordingly. In order to instantiate such a class it would be necessary to specify the exact type. This is not a problem for a standalone property, but in an array there should be possible to store elements with different exact types.

Is there a way how to express this in Swift?


Solution

  • I just came across this old question of mine and because the Swift language evolved since accepting the partial answer I decided to post another answer which actually solves the problem I originally asked.

    From version 4, Swift supports protocol composition using the & sign which can also be composed with one class type.

    class BaseClass {}
    protocol Protocol1 {}
    protocol Protocol2 {}
    
    class ConformingClass1: BaseClass, Protocol1, Protocol2 {}
    class ConformingClass2: BaseClass, Protocol1, Protocol2 {}
    
    // It works for a variable holding a single object.
    let object: BaseClass & Protocol1 & Protocol2 = ConformingClass1()
    
    // And it also works for a variable holding an array of objects.
    let array: [BaseClass & Protocol1 & Protocol2] = [ConformingClass1(), ConformingClass2()]