Swift - 关闭中的泛型

lin*_*use 0 generics closures swift

我来自.NET世界,所以我对Swift中如何实现泛型有点困惑.我正在尝试执行以下操作:

func request<T: Model>(resultHandler: (model: T?) -> ()) {
        var model: T? = nil

        NSURLSession.sharedSession().dataTaskWithURL(NSURL(string: self.url)!) {
            data, response, error in
                if let json = NSString(data: data, encoding: NSUTF8StringEncoding) {
                    model = T(json: json)

                    resultHandler(model: model)
                }
            }.resume()
    }
Run Code Online (Sandbox Code Playgroud)

并按如下方式使用它:

var store: HttpStore = HttpStore(url: ...)

store.request {
            model in
                println("Task name: \(model.name!)")
        }
Run Code Online (Sandbox Code Playgroud)

我收到以下错误:

'T?' 没有名为'name'的成员

我明白了.我没有在我的调用代码中的任何地方解析T到特定类型.在.NET中我会做类似store.request <Task>()...但我不能在Swift中这样做.

有没有办法完成我在这里要做的事情?

Mar*_*n R 5

闭包表达式通常具有形式

{ (param_1 : type_1, ..., param_n : type_n ) -> return_type in
    statements
}
Run Code Online (Sandbox Code Playgroud)

当闭包类型已知或可以从上下文中推断出时,您可以省略参数类型,返回类型(以及参数周围的括号):

{ param_1, ..., param_n in
    statements
}
Run Code Online (Sandbox Code Playgroud)

但是在你的代码中

store.request {
    model in
    // ...
}
Run Code Online (Sandbox Code Playgroud)

无法从上下文中推断出闭包的类型,您必须将其明确地写为

store.request {
    (model : Task?) -> () in
    // ...
}
Run Code Online (Sandbox Code Playgroud)

或(返回类型()Void可以省略):

store.request {
    (model : Task?) in
    // ...
}
Run Code Online (Sandbox Code Playgroud)

请注意,块内部model可选的.正如安东尼奥已经在一个现在删除的答案中所说,你将不得不打开可选的,所以

println("Task name: \(model.name!)")
Run Code Online (Sandbox Code Playgroud)

应该是

println("Task name: \(model!.name)")
Run Code Online (Sandbox Code Playgroud)

如果model可能nil那么你可以使用可选的绑定来测试它:

if let theModel = model {
    println("Task name: \(theModel.name)")
}
Run Code Online (Sandbox Code Playgroud)