Swift protocol extension with property conforming to protocol

时间:2016-02-14 09:56:13

标签: swift protocols swift-protocols

I declared a protocol like so

protocol JSONConnection {
  var request: NSURLRequest { get set }
  var session: NSURLSession { get set }
  var jsonRootObject: JSONSerializable? { get set }
}

Here, the JSONSerializable is not an actual type, it is another protocol that I declared like so:

protocol JSONSerializable {
  func readFromJSON(json: JSON) throws
}

So, in fact, this JSONConnection protocol requires a variable called jsonRootObject that just needs to conform to the JSONSerializable protocol.

Fine.


Now, for the implementations.

I created a class called JSONStockDetailRootObject that conforms to the JSONSerializable protocol.

class JSONStockDetailRootObject: JSONSerializable

And I wanted to create a StockConnection class that conforms to the JSONConnection protocol.

class StockConnection: JSONConnection {
  var request: NSURLRequest
  var session: NSURLSession
  var jsonRootObject: JSONStockDetailRootObject?
}

I thought that, if I had a jsonRootObject variable of a type that conformed to the JSONSerializable protocol, then this class StockConnection would in turn conform to the JSONConnection protocol ... but no.

The compiler claims: "Protocol requires property 'jsonRootObject' with type 'JSONSerializable?'

What am I missing? Thanks

1 个答案:

答案 0 :(得分:5)

在您的示例中,类StockConnection不包含蓝图var jsonRootObject: JSONSerializable? { get set }的任何有效实现,它承诺通过符合JSONConnection来实现。请注意,在jsonRootObject的上下文中,JSONSerializable类型,即使JSONStockDetailRootObject 符合JSONSerializable ,它不能被视为相同的类型。

您可以通过在协议T中引入一个类型,即jsonRootObject,(用作JSONConnection类型)来解决此问题;其中T被约束为符合JSONSerializable的类型。

protocol JSONSerializable {
    func readFromJSON(json: JSON) throws
}

protocol JSONConnection {
    typealias T: JSONSerializable
    var request: NSURLRequest { get set }
    var session: NSURLSession { get set }
    var jsonRootObject: T? { get set }
}

class JSONStockDetailRootObject: JSONSerializable {
    func readFromJSON(json: JSON) throws ...
}

class StockConnection: JSONConnection {
    var request: NSURLRequest = NSURLRequest()
    var session: NSURLSession = NSURLSession()
    var jsonRootObject: JSONStockDetailRootObject?
}

由于JSONStockDetailRootObject符合JSONSerializable,上述jsonRootObjectStockConnection的实施符合协议var jsonRootObject: T? { get set }中蓝图JSONConnection的有效一致性。