0

Say you have some abstraction, like Filter, and you want an array of them. Different filters deal with different types of values, so you want to make that something like a type parameter or associated type. But the array can have different kinds of filters. Something like this...

class Filter<T> ...
class AFilter : Filter<A> ...
class BFilter : Filter<B> ...
var filters: [Filter<?>]  // not real swift syntax
filters.append( AFilter() )
filters.append( BFilter() )

I tried with a protocol ...

protocol Filter {
    associatedtype Value : CustomStringConvertible
    var name: String { get }
    func doSomething(with: Value)
    func doMore(with: Value)
}

class FilterCollection {
    var filters: [Filter] = []  // error here
}

The compiler error is: protocol 'Filter' can only be used as a generic constraint because it has Self or associated type requirements

Update

People have suggested this is a duplicate. I'm going to have to run some experiments to see if I can use this erasure technique. I like that it's better type safety than simply using [Any]

class AnyFilter {
    private let f: Any
    init<T> (_ f: T) where T : Filter {
        self.f = f
    }
}

class FilterCollection {
    var filters: [AnyFilter] = []
}
Rob N
  • 15,024
  • 17
  • 92
  • 165
  • You want a [type erasure](http://robnapier.net/erasure) – Hamish Oct 14 '16 at 17:25
  • The problem with wanting a heterogenous array of `Filter`s is that the `doSomething(with:)` and `doMore(with:)` methods will have concrete typed parameters – therefore there's no way to generalise their input. Therefore if you build a type erasure, you'll have to drop the forwarding of those methods. Perhaps if you showed us a more concrete example, it would be easier to help you. – Hamish Oct 14 '16 at 17:42
  • Related: [How do I add different types conforming to a protocol with an associated type to a collection?](http://stackoverflow.com/questions/31762045/how-do-i-add-different-types-conforming-to-a-protocol-with-an-associated-type-to) – Hamish Oct 14 '16 at 17:44
  • I need to experiment. But maybe in my case the more fitting thing to is split Filter into two classes, a base class without the type parameter, and the rest. – Rob N Oct 14 '16 at 18:32

0 Answers0