Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Swift restrict generic type to Type

How can I restrict a generic type to be a type, not an instance of a type?

If I have a class:

class SomeClass<T: SomeProtocol> {}

how can I ensure that T is only an instance of AnyClass (which is just AnyObject.Type)

My protocol only has static methods and in order to call those methods I have to do instance.dynamicType.protocolMethod whereas I want to do someType.protocolMethod

like image 999
barndog Avatar asked Nov 09 '22 02:11

barndog


1 Answers

AFAIK, Swift does not allow you to use a metatype as a generic type. (I believe this is along the lines of what Sam Giddins wished for in Swift 3.)

You can, however, use it as a value. Instead of making T a type parameter, make it a property:

protocol SomeProtocol {
    static func foo()
}

struct Concrete: SomeProtocol {
    static func foo() {
        print("I am concrete")
    }
}

class SomeClass {
    let T: SomeProtocol.Type

    init(T: SomeProtocol.Type) {
        self.T = T
    }

    func go() {
        T.foo()  // no need for dynamicType
    }
}

SomeClass(T: Concrete.self).go()

If, as you say, your protocol contains only static methods, then this is sufficient. However, if you need to tie a generic parameter to the type, that’s possible too:

class SomeClass<U: SomeProtocol> {
    let T: U.Type

    init(T: U.Type) {
        self.T = T
    }

    func go(value: U) {
        T.foo()
    }
}

SomeClass(T: Concrete.self).go(Concrete())
like image 117
Paul Cantrell Avatar answered Nov 14 '22 22:11

Paul Cantrell