简体   繁体   中英

Pass dynamic type as parameter

What I want to accomplish is to pass the dynamic type of object as a parameter to generic function. I'm able to see the correct type I want with type(of:) , but I'm unable to pass it as parameter, because in generic function I'm still getting the static type . Here is an example what I want to do:

protocol SomeUsefulProtocol {}

struct MyType1: SomeUsefulProtocol {}
struct MyType2: SomeUsefulProtocol {}

let objects: [SomeUsefulProtocol] = [MyType1(), MyType2()]

let someClosureToWorkWithMyType: Any = { (object: MyType1) in
    //Do some great things
}

func someMethod<T>(type: T.Type, object: Any) {
    typealias ClosureType = (T) -> Void

    if let closure = someClosureToWorkWithMyType as? ClosureType, let object = object as? T {
        closure(object)
    }
}

for object in objects {
    someMethod(type: type(of: object), object: object)
}

Here i want closure someClosureToWorkWithMyType to be called when object has a type 'MyType1', but inside the method the type of object is the static type (SomeUsefulProtocol).

The problem here is that object as declared as an instance of the protocol SomeUsefulProtocol . An instance of a protocol is not any specific concrete type, and can be one of potentially many concrete types.

Swift's generics system requires known concrete types at compile time to create the right specializations. There are a number of blog posts and StackOverflow questions and answers which delve deeper into the trickiness (and more often than not, the futility)of trying to use Swift protocols and Swift generics together.

In your specific example, your method can be made to work in one of two ways: either don't declare object as a protocol instance, but instead make it a concrete type, eg

let object: MyType = MyType()

Or keep it declared as-is, but cast it to a concrete type when passing it into your function, eg

(object as? MyType).flatMap{ someMethod(type: type(of: $0), object: $0) }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM