generics - Swift - 闭包中的泛型

标签 generics swift closures

我来自 .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()
    }

并按如下方式使用它:

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

store.request {
            model in
                println("Task name: \(model.name!)")
        }

我收到以下错误:

'T?' does not have a member named 'name'

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

有什么方法可以完成我在这里要做的事情吗?

最佳答案

闭包表达式通常具有以下形式

{ (param_1 : type_1, ..., param_n : type_n ) -> return_type in
    statements
}

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

{ param_1, ..., param_n in
    statements
}

但是在你的代码中

store.request {
    model in
    // ...
}

闭包的类型不能从上下文中推断出来,你必须写 它明确地作为

store.request {
    (model : Task?) -> () in
    // ...
}

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

store.request {
    (model : Task?) in
    // ...
}

请注意,在 block 内,model 是一个可选。作为Antonio已经在现已删除的答案中说过, 你将不得不打开可选的,所以

println("Task name: \(model.name!)")

应该是

println("Task name: \(model!.name)")

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

if let theModel = model {
    println("Task name: \(theModel.name)")
}

关于generics - Swift - 闭包中的泛型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27890798/

相关文章:

ios - 将 HTML 字符串转换为 NSAttributedString 时运行 Archive 时崩溃

javascript - 从 typescript 中的通用类扩展的类扩展

ios - 过滤里面有字典的 NSArray - swift 1.2

ios - 快速打开一个元组

ios - 在 UIImageView 后面插入子层

swift - Swift 中的宏闭包

javascript - javascript 中嵌套匿名方法的闭包

java - Java内部类需要final变量的复杂性?

c# - 如何检测一个对象是否属于泛型 List 类型并转换为所需的类型?

java - 解释泛型如何在此方法中工作