【问题标题】:Generic protocol extension and `Self`通用协议扩展和`Self`
【发布时间】:2015-08-31 13:35:36
【问题描述】:

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

protocol BulkFetchable {

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

}

我用一个通用的实现扩展了这个协议(忽略端点是固定的这个问题的事实):

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

}

我正在使用 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
        }
    })
}

}

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

extension User : BulkFetchable {}

唉,我收到错误:

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

我能做些什么来解决这个问题?我希望Self 在扩展User 的上下文中自动变为User,但这可能是由于我缺乏理解。

【问题讨论】:

  • 什么是结果
  • 嗨@GeneratorOfOne,我添加了更多上下文。它无法编译——因此是问题所在!
  • Result 在 Alamofire 中是具有 2 个参数的泛型,不是 1,不是吗? public enum Result&lt;Value, Error: ErrorType&gt;
  • 感谢@Brynjar,但这是使用先前版本的 Alamofire,它具有不同的 Result 结构。

标签: swift generics


【解决方案1】:

我正在做类似的事情并偶然发现了同样的错误。

我对此的有限理解(主要来自于 WWDC 2015 herehere 录制的两个视频)表明您的类 User 需要声明为:

final class User {...}

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

fetch() 应该返回 Self 的同构数组(在本例中为 User),如果 User 被子类化(并且 fetch() 被覆盖),它将返回子类的数组。或者在一个容易想象的世界中,User 及其子类的数组。不是超级班级BulkFetchable 所期待的!

【讨论】:

    猜你喜欢
    • 2017-04-24
    • 1970-01-01
    • 1970-01-01
    • 2021-09-20
    • 1970-01-01
    • 2016-07-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多