2016-05-16 14 views
5

Tôi có giao thức sau đây và mở rộng của nógiao thức Swift với kiểu gắn liền - loại có thể không tham khảo chính nó như là một yêu cầu

public protocol RESEndpointReachable: CustomDebugStringConvertible 
{ 
    associatedtype EndpointType: RESEndpointReachable 


    // MARK: - Properties 

    /// The name of the endpoint as defined in the REST URI. 
    var name: String { get } 

    /// An array of possible next endpoints that this endpoint can reach. E.g account's next endpoints would be authenticate and unauthenticate. 
    var nextPossibleEndpoints: [EndpointType] { get } 


    // MARK: - Ability 

    /// Used to process the endpoint. 
    func processRequest(request: RERequest) 

    /// Processes the next endpoint that matches the name `name`. Expects an endpoint with the name `name` to exist in `nextPossibleEndpoints`. 
    func processNextEndpointWithName(name: String, request: RERequest) 
} 

public extension RESEndpointReachable 
{ 
    // MARK: - CustomDebugStringConvertible 

    public var debugDescription: String { 
     return name 
    } 


    // MARK: - RESEndpointReachable 

    var nextPossibleEndpoints: [EndpointType] { 
     return [] 
    } 

    public func processRequest(request: RERequest) 
    { 
     // Check all possible endpoints are being processed 
     if let nextEndpoint = nextPossibleEndpoints.first 
     { 
      fatalError("Unhandled endpoint \(nextEndpoint).") 
     } 
    } 

    public func processNextEndpointWithName(name: String, request: RERequest) 
    { 
     // Get the next endpoint that matches the specified name 
     let nextEndpoints = nextPossibleEndpoints.filter { $0.name == name } 

     if nextEndpoints.count > 1 
     { 
      fatalError("Multiple next endpoints found with the name '\(name)'.") 
     } 

     guard let nextEndpoint = nextEndpoints.first else 
     { 
      fatalError("No next endpoint with the name '\(name)'.") 
     } 


     // Process the next endpoint 
     nextEndpoint.processRequest(request) 
    } 
} 

On xây dựng, dòng associatedtype EndpointType: RESEndpointReachable có các lỗi sau: Type may not reference itself as a requirement. Nhưng như tôi đã hiểu, đây là cách bạn sử dụng các kiểu liên kết trong Swift.

Như bạn có thể đã đoán, tôi luôn muốn bất cứ điều gì EndpointType kết thúc được đặt làm loại được kế thừa từ RESEndpointReachable.

+0

Tôi không sử dụng tính năng này ble ngay bây giờ! Tham khảo: https://gist.github.com/curtclifton/1923a47774a94e904bf0 https://forums.developer.apple.com/thread/15256. Nó sẽ làm cho trình biên dịch chạy trong vòng lặp đệ quy – sargeras

+0

Cảm ơn :) Tôi nghĩ rằng có thể là trường hợp ... Có lẽ tháng sau ... –

Trả lời

3

Tính năng này được giới thiệu bởi nhóm Swift là 'ràng buộc giao thức đệ quy' và đang trên lộ trình được thêm vào trong phiên bản Swift mới trong tương lai. Để biết thêm thông tin về tính năng này và các tính năng được lên kế hoạch khác, hãy xem nhóm Swift của 'Completing Generics' manifesto.

+0

Dường như vô lý với tôi, rằng Swift 4 vẫn không hỗ trợ điều này -.- – d4Rk

+0

Theo nhận xét của Doug Gregor trong vấn đề theo dõi này (https://bugs.swift.org/browse/SR-1445), nó đã được phát hành với Swift 4.1, do đó, Xcode mới nhất _should_ ship với một trình biên dịch hỗ trợ nó. (Chưa tự mình thử, vì vậy tôi không biết tính năng hoạt động tốt như thế nào trong thực tế ...) – AustinZ

1

Đúng, điều đó không ổn với tốc độ nhanh. Một giao thức không thể sử dụng nó như một ràng buộc kiểu. Một giải pháp là tuyên bố một giao thức bổ sung là RESEndpointReachable chính nó sẽ áp dụng và hạn chế RESEndpointReachable với giao thức siêu đó.

tôi lấy ví dụ từ cuốn sách iOS 10 Lập trình cơ bản với Swift bởi Neuburg M. (xin xem trang 194)

dụ bất hợp pháp:

1 protocol Flier { 
    2   associatedtype Other : Flier 
    3   func flockTogetherWith(_ f: Other) 
    4 } 
    5 
    6 struct Bird : Flier { 
    7   func flockTogetherWith(_ f: Bird) {} 
    8 } 

Giải pháp:

1 protocol Superflier {} 
    2 protocol Flier: Superflier { 
    3   associatedtype Other : Superflier 
    4   func flockTogetherWith(_ f: Other) 
    5 }  
    6 
    7 struct Bird : Flier { 
    8   func flockTogetherWith(_ f: Bird) {} 
    9 } 

Chúc mừng

Các vấn đề liên quan