Feenaboccles
Feenaboccles

Reputation: 412

What is the type of an array of SequenceTypes generating the same type of class

I have a bunch of classes that are very different, except they are all capable of returning objects of type MyProtocol.

So for each class I have

extension MyClass : SequenceType {
    func generate() -> GeneratorOf<MyProtocol> {
        var index = -1;
        return GeneratorOf< MyProtocol > {
            index += 1
            return index < self.values.count
                ? self.values[index]
                : nil
        }
    }
}

I want to pass a collection of such classes to a function that can do

func printAll (containers : ????) {
    for container : containers {
        for myProtocolValue : container { 
            print (myProtocolValue.myProtocolFunc())
        }
    }
}

What type does containers have?

Upvotes: 0

Views: 29

Answers (1)

Qbyte
Qbyte

Reputation: 13253

The best solution would be to make a new protocol. All of your classes conform to it and it has no self requirements in order to use heterogeneous Arrays:

protocol MyProtocolContainer {
    func generate() -> GeneratorOf<MyProtocol>
}

// the implementation of the generate function stays the same but you conform to MyProtocolContainer

extension MyClass : SequenceType, MyProtocolContainer { ... }

// the printAll function has the following implementation
func printAll (containers : [MyProtocolContainer]) {
    for container in containers {
        // you have to call generate manually since MyProtocolContainer is no SequenceType
        // in order to be used in a heterogenous collection
        for myProtocolValue in container.generate() { 
            print (myProtocolValue.myProtocolFunc())
        }
    }
}

Side note:

in Swift there are no for ... : ... loops the : should be an in.

To make the implementation of the generate function easier I would suggest to use the Generator of the Array itself:

class MyClass: MyProtocolReturnable, SequenceType {
    func generate() -> GeneratorOf<MyProtocol> {
        return GeneratorOf(self.values.map{ $0 as MyProtocol }.generate())
        // if the array is of type [MyProtocol] you can also use
        return GeneratorOf(self.values.generate())
    }
}

Upvotes: 1

Related Questions