通用协议扩展和“自我”

时间:2015-08-31 13:35:36

标签: swift generics

我有一个协议,定义了从服务器获取对象数组的能力。 Result中定义了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)
    }

}

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

Request

我正在使用Alamofire T的扩展程序,它将JSON响应转换为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 {} 模型这个能力:

Self

唉,我收到错误:

  

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

我该怎么做才能解决这个问题?我希望UserUser扩展的上下文中自动变为<script src="~/Scripts/Items.js"></script> <div ng-app="SearchModule"> <div ng-controller="SearchSomething" class="col-md-1"> <input class="searchClass" type="text" placeholder="Search" /> </div> </div> ,但这可能是由于我缺乏理解。

1 个答案:

答案 0 :(得分:6)

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

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

<强> final class User {...}

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

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