首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在泛型上尾随闭包?

在泛型上尾随闭包?
EN

Stack Overflow用户
提问于 2016-01-09 16:36:22
回答 2查看 231关注 0票数 1

嗨,我正在试着理解以下来自阿拉莫火的代码。如何用"{}“初始化一个结构--我知道你可以用尾随闭包来调用一个闭包。我知道我完全错过了什么,但是什么?

代码语言:javascript
复制
extension Request {
    public func responseObject<T: ResponseObjectSerializable>(completionHandler: Response<T, NSError> -> Void) -> Self {

        let responseSerializer = ResponseSerializer<T, NSError> { // What is this?
                request, response, data, error in
                guard error == nil else { return .Failure(error!) }

            let JSONResponseSerializer = Request.JSONResponseSerializer(options: .AllowFragments)
            let result = JSONResponseSerializer.serializeResponse(request, response, data, error)

            switch result {
            case .Success(let value):
                if let
                    response = response,
                    responseObject = T(response: response, representation: value)
                {
                    return .Success(responseObject)
                } else {
                    let failureReason = "JSON could not be serialized into response object: \(value)"
                    let error = Error.errorWithCode(.JSONSerializationFailed, failureReason: failureReason)
                    return .Failure(error)
                }
            case .Failure(let error):
                return .Failure(error)
            }
        }

        return response(responseSerializer: responseSerializer, completionHandler: completionHandler)
    }
}

阿拉莫火的结构ResponseSerializer

代码语言:javascript
复制
public struct ResponseSerializer<Value, Error: ErrorType>: ResponseSerializerType {
    /// The type of serialized object to be created by this `ResponseSerializer`.
    public typealias SerializedObject = Value

    /// The type of error to be created by this `ResponseSerializer` if serialization fails.
    public typealias ErrorObject = Error

    /**
        A closure used by response handlers that takes a request, response, data and error and returns a result.
    */
    public var serializeResponse: (NSURLRequest?, NSHTTPURLResponse?, NSData?, NSError?) -> Result<Value, Error>

    /**
        Initializes the `ResponseSerializer` instance with the given serialize response closure.

        - parameter serializeResponse: The closure used to serialize the response.

        - returns: The new generic response serializer instance.
    */
    public init(serializeResponse: (NSURLRequest?, NSHTTPURLResponse?, NSData?, NSError?) -> Result<Value, Error>) {
        self.serializeResponse = serializeResponse
    }
}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-01-09 17:01:24

你的问题可以大大减少(而且应该是这样)。以下是ResponseSerializer的相关声明:

代码语言:javascript
复制
public struct ResponseSerializer<Value, Error: ErrorType>: ResponseSerializerType {
    public init(serializeResponse: (NSURLRequest?, NSHTTPURLResponse?, NSData?, NSError?) -> Result<Value, Error>) {
        self.serializeResponse = serializeResponse
    }
}

因此,这个初始化器init(serializeResponse:)接受一个参数--一个函数接受四个参数,并返回一个参数(指定类型的参数)。

因此,我们可以像这样初始化:

代码语言:javascript
复制
func f (request:NSURLRequest?, response:NSHTTPURLResponse?, data:NSData?, error:NSError?) -> Result<Value, Error>)  {
    guard error == nil else { return .Failure(error!) 
}
let responseSerializer = ResponseSerializer<T, NSError>(serializeResponse:f)

然而,这是可以浓缩的。我们实际上不需要函数f,所以我们可以将其作为匿名函数提供;它不需要名称或完整的声明。此外,对于匿名函数有一个“快捷”规则,如果匿名函数是函数的最后一个参数,则可以在函数的结束括号之后按字面顺序提供它,并省略参数名称。如果该函数不接受其他参数,则可以完全省略它的括号。

嗯,这个init正是这样一个函数--它接受一个函数作为它的最后(也是唯一)参数--所以这正是所讨论的代码所做的:

代码语言:javascript
复制
let responseSerializer = ResponseSerializer<T, NSError> { 
    request, response, data, error in
    guard error == nil else { return .Failure(error!) 
}
票数 1
EN

Stack Overflow用户

发布于 2016-01-09 17:01:44

如果我正确地阅读了这些代码,那么上面的代码有一个类似的模式:

代码语言:javascript
复制
// just a something

struct Blah {
    var stuffs : (message:String) -> Void

    init(closure:(message:String) -> Void) {
        self.stuffs = closure
    }
}

// an extension because the code above is also in an extension, but not needed at all
extension Blah {

// a function with a closure that also returns an instance of Self
    func spawnChild(closure:(message:String) -> Void) -> Blah {

        return Blah(closure: closure) // closure is passed to spawn

    }

}

测试:

代码语言:javascript
复制
let alpha = Blah { (message) -> Void in
    print("alpha",message)
}

let beta = alpha.spawnChild { (message) -> Void in
    print("beta", message)
}

alpha.stuffs(message: "parrent") // alpha parent
beta.stuffs(message: "spawn") // beta spawn

请记住,尾随闭包只是输入参数(即闭包)的语法糖。因此,任何接受输入参数的都会有一个尾随闭包。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34696042

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档