swift - 泛型的尾随闭包?

标签 swift

您好,我正在尝试理解以下来自 Alamofire 的代码。如何使用“{}”初始化结构我知道您可以使用尾随闭包调用闭包。我知道我完全错过了一些东西,但是什么?

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)
    }
}

Alamofire 的 ResponseSerializer 结构体

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
    }
}

最佳答案

您的问题可以大大减少(并且应该减少)。下面是ResponseSerializer的相关声明:

public struct ResponseSerializer<Value, Error: ErrorType>: ResponseSerializerType {
    public init(serializeResponse: (NSURLRequest?, NSHTTPURLResponse?, NSData?, NSError?) -> Result<Value, Error>) {
        self.serializeResponse = serializeResponse
    }
}

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

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

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 就是这样一个函数——它把一个函数作为它的最后一个(也是唯一的)参数——所以这正是有问题的代码所做的:

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

关于swift - 泛型的尾随闭包?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34696042/

相关文章:

arrays - Swift Array 实例方法 drop(at : Int)

ios - 使用 "dependencies"继承自定义 ViewController 的正确方法

iphone - View Controller 之间的数据未传递

ios - 如何使用用户键入消息更改 UILabel 文本

swift - 类在两者中都实现...将使用两者之一。定义的是哪一个

arrays - 获取字典数组中的重复值。 swift

json - 异步问题: Calling Web Api from Swift

arrays - 如何查找/过滤具有最小正差的数组元素

ios - 如何在不使用 MusicKit 的情况下访问用户的音乐库?

ios - 如何在不同设备的段控制中管理文本大小?