Swift Covariant Generics

Here is an example of what I’d like to achieve:

protocol SomeType {}

class SomeClass: SomeType {}

struct SomeGenericStruct<A> {
    typealias E = A
}

func take(someType: SomeGenericStruct<SomeType>) {}

let concreteGenericStruct1: SomeGenericStruct<SomeType> = SomeGenericStruct<SomeType>()
let concreteGenericStruct2: SomeGenericStruct<SomeClass> = SomeGenericStruct<SomeClass>()

take(concreteGenericStruct1)
take(concreteGenericStruct2) // much no work, very repair. wow.

Or even simpler:

  • Assertion failure when using UISearchDisplayController in UITableViewController
  • How can I concatenate NSAttributedStrings?
  • How to trigger Core Bluetooth state preservation and restoration
  • What exactly is init coder aDecoder?
  • Why I'm getting gesture recognizers cannot be used on prototype objects?
  • UIButton Image + Text IOS
  • let concreteGenericStruct3: SomeGenericStruct<SomeType> = SomeGenericStruct<SomeClass>() as SomeGenericStruct<SomeType> // still no work
    

    How can I manage to provide take with concreteGenericStruct2?

    Solutions Collect From Internet About “Swift Covariant Generics”

    You can use generic method for this:

    func take<T where T: SomeType>(someType: SomeGenericStruct<T>) { }
    

    The only problem with this is that you can not pass SomeGenericStruct<SomeType> to it. It must be a generic of some concrete type instead. If totally necessary, you can just have two functions doing the same thing essentially:

    func take(someInput: SomeGenericStruct<SomeType>) { /* do stuff */ }
    func take<T where T: SomeType>(someType: SomeGenericStruct<T>) { /* do same stuff */ }