转换为指定的泛型函数参数

时间:2016-09-09 10:33:38

标签: swift generics casting

假设我有一个执行命令的Commander对象。返回类型并不总是相同的,并根据命令进行更改。

我希望能够使用一个将命令转发给Commander的函数,测试结果是否属于某种类型(作为参数传递),如果转换成功则调用成功闭包,以及否则就会失败。

我尝试过使用类似这样的通用参数:

func postCommand<T>(command: String, expectedResponseType: T, success: T -> Void, failure: (NSError?) -> Void) {
    Commander.execute(command, completion: { (response: AnyObject?) in
        guard let content = response as? T else {
            failure(nil)
            return
        }
        success(content)
    })
}

以这种方式调用

self.postCommand("command", expectedResponseType: [String: AnyObject], success: { (content: [String: AnyObject]) in
    print("Success")
}) { (error: NSError?) in
    print("Failure")
}

但是我收到编译器的错误:

Cannot convert value of type '([String : AnyObject]) -> Void' to expected argument type '_ -> Void'

如果我尝试像这样做演员:

guard let content = response as? expectedResponseType

编译器抱怨expectedResponseType不是类型。

我无法弄清楚如何做到这一点。它甚至可能吗?

1 个答案:

答案 0 :(得分:1)

问题不在于强制转换,而在于expectedResponseType:参数的类型。

如果您希望将类型传递给函数,则需要使用the metatype type作为参数类型。在这种情况下,函数的expectedResponseType:参数应为T.Type类型 - 允许您传入一个类型来定义T

func postCommand<T>(_ command: String, expectedResponseType: T.Type, success: (T) -> Void, failure: (NSError?) -> Void) {
    // ...
}

您还需要使用后缀.self来引用传递给expectedResponseType:参数的实际类型:

self.postCommand("command", expectedResponseType: [String: AnyObject].self, success: { content in
    print("Success")
}) { error in
    print("Failure")
}

虽然您应该注意T的类型可以直接从成功闭包中推断出来,然后传递给函数:

func postCommand<T>(_ command: String, success: (T) -> Void, failure: (NSError?) -> Void) {
    // ...
}

self.postCommand("command", success: { (content: [String: AnyObject]) in
    print("Success")
}) { error in
    print("Failure")
}