通用协议扩展和"自我"

Ale*_*lex 1 generics swift

我有一个协议,定义从服务器获取对象数组的能力.ResultAlamofire中定义:

protocol BulkFetchable {

    static func fetch(limit : Int, skip : Int, completionHandler : ((request : NSURLRequest?, response : NSHTTPURLResponse?, result : Result<[Self]?>) -> Void)) -> Request

}
Run Code Online (Sandbox Code Playgroud)

我使用通用实现来扩展此协议(忽略端点为此问题的目的而修复的事实):

extension BulkFetchable where Self : Mappable {

    static func fetch(limit: Int, skip: Int, completionHandler: ((request: NSURLRequest?, response: NSHTTPURLResponse?, result: Result<[Self]?>) -> Void)) -> Request {
        return Alamofire.request(.GET, "http://localhost:4567/users.json", parameters: ["limit" : limit, "skip" : skip], encoding: .URL, headers: nil).responseArray(completionHandler)
    }

}
Run Code Online (Sandbox Code Playgroud)

我正在使用Alamofire的扩展Request,将JSON响应转换为可选的类型数组T,其中T采用Mappable:

extension Request {

func responseArray <T : Mappable> (completionHandler: (NSURLRequest?, NSHTTPURLResponse?, Result<[T]?>) -> Void) -> Self {
    return responseJSON(completionHandler: { (req, res, result) -> Void in
        switch result {
        case .Success(let json):
            completionHandler(req, res, .Success(Mapper<T>().mapArray(json)))
            break
        case .Failure(let data, let error):
            completionHandler(req, res, .Failure(data,error))
            break
        }
    })
}

}
Run Code Online (Sandbox Code Playgroud)

然后,我给我的User模型这个能力:

extension User : BulkFetchable {}
Run Code Online (Sandbox Code Playgroud)

唉,我收到错误:

协议'BulkFetchable'要求'fetch(_:skip:completionHandler :)'不能被非最终类('User')满足,因为它在非参数非结果类型位置使用'Self'

我该怎么做才能解决这个问题?我希望Self自动变成User扩展的上下文User,但这可能是由于我缺乏理解.

小智 6

我做了类似的事情并且偶然发现了同样的错误.

我对此的理解有限(主要来自WWDC 2015 此处此处录制的两个视频)表明您的班级用户需要声明为:

final class User {...}

这是因为fetch()调用不必被子类覆盖.

fetch()应该返回Self的同源数组(在这种情况下User),如果User是子类(并fetch()覆盖),它将返回子类的数组.或者在一个容易想象的世界中,一个数组User及其子类.不是超级班的BulkFetchable期待!