2016-05-16 41 views
5

aşağıdaki protokolü ve onun uzantısı bina üzerindeSwift protokol - tipi bir şartı

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

sahip olarak kendini referans olmayabilir, satır associatedtype EndpointType: RESEndpointReachable aşağıdaki hata var: Type may not reference itself as a requirement. Ama anladığım kadarıyla, Swift'de ilişkili türleri nasıl kullanıyorsunuz.

Tahmin ettiğiniz gibi, her zaman 'un, RESEndpointReachable'dan devralınacak bir tür olarak ayarlanmasını istiyor.

+0

Bu özellik possi değil Şimdi sağ salla! Ref: https://gist.github.com/curtclifton/1923a47774a94e904bf0 https://forums.developer.apple.com/thread/15256. Bu özyinelemeli döngüler içinde – sargeras

+0

Teşekkür derleyici çalışmasını sağlayacaktır :) Ben durumun olabileceğini düşündüm ... Belki gelecek ay ... –

cevap

3

Bu özellik 'özyinelemeli protokol kısıtlamaları' olarak Swift ekip tarafından sevk ve planlarımız dahilinde olan Swift gelecekteki bir sürümüne eklenecek. Bu ve diğer planlanan özellikler hakkında daha fazla bilgi için Swift ekibinin 'Completing Generics' manifesto'a bakın.

+0

bana saçma görünüyor, Swift 4 hala bu -.- – d4Rk

+0

Doug Gregor'un yorumuna göre desteklemediği sayısında bu (https://bugs.swift.org/browse/SR-1445), bu Swift 4.1 ile serbest bırakıldı izleme, böylece son Xcode bunu destekleyen bir derleyici ile _should_ gemi. (Kendim denemedim, bu yüzden bu özelliğin pratikte ne kadar iyi çalıştığını bilmiyorum ...) – AustinZ

1

Evet, bu hızlı bir şekilde tamam değil. Bir protokol kendi kendini tip kısıtlaması olarak kullanamaz. Bir çözüm RESEndpointReachable kendisi süper protokole RESEndpointReachable benimsemek ve kısıt edecek ekstra bir protokol beyan etmektir.

ben (lütfen sayfa 194), Neuburger M. Swift ile kitaptan iOS 10 Programlama Temelleri örnek aldı

yasadışı örnek:

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

Çözüm:

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 } 

Şerefe