Morpheus
Morpheus

Reputation: 1319

Array of generic classes and subclassing

I'm having trouble wrapping my head around generics. What I want is to have an array of generic classes, each with it's own associated type, and call a function accordingly. It would look something like this:

class SomeGenericClass<U> {
    func addCallback(callback: (U)->() ) { ... }
}

var array: [SomeGenericClass] // compile error

The last line yields an error, so I found that I needed to have a superclass. I tried something like this:

class SuperClass {
    func addCallback<V>(callback: (V)->() ) { ... }
}

class SomeGenericClass<U> {
    func addCallback<V: U>(callback: (V)->() ) { ... } // compile error
}

var array: [SuperClass] // no compile error

This yields the error Type 'V' constrained to non-protocol, non-class type 'U'.

Basically I want to be able to do:

array.append(SomeGenericClass<UIImage>()) // array[0]
array.append(SomeGenericClass<Int>()) // array[1]

// Since array[0] is effectively of type SomeGenericClass<UIImage>, the compiler should understand that the close added if of type (UIImage)->(), and therefore that value is of type UIImage
array[0].addCallback { value in
   someImageView.image = value
}

Is using a superclass the right approach in this case? How should it be implemented?

Upvotes: 2

Views: 64

Answers (1)

Morpheus
Morpheus

Reputation: 1319

I worked around this problem by storing my array members in their own variable. That is, instead of defining my array like:

lazy var array: [SuperClass] = [
    SomeGenericClass<UIImage>(),
    SomeGenericClass<Int>(),
    //etc...
]

I defined it this way:

lazy var genericFirst: SomeGenericClass<UIImage> = SomeGenericClass<UIImage>()
lazy var genericSecond: SomeGenericClass<Int> = SomeGenericClass<Int>()
// etc...

lazy var array: [SuperClass] = [
    genericFirst,
    genericSecond,
    //etc...
]

This way, I can access the generics I want like this:

genericFirst.addCallback { value in
    // value is indeed of type UIImage
    someImageView.image = value
}

Upvotes: 1

Related Questions