2017-03-18 1 views
0

Prenons l'exemple suivant:Comment invoquer la mise en œuvre par défaut d'extension de protocole avec des contraintes de type

class ManObj { 
    func baseFunc() { 
     print("ManObj baseFunc") 
    } 
} 

class SubObj: ManObj { 
} 

protocol Model { 
} 

extension Model { // This is protocol extension 
    func someFunc() { // Protocol extension default implementation 
     (self as! ManObj).baseFunc() 
     print("Model implementation") 
    } 
} 
extension SubObj: Model { 
    func someFunc() { 
     print("SubObj Implementation") 
    } 
} 

let list = SubObj() 
list.someFunc() // static dispatching 

let list2: Model = SubObj() 
list2.someFunc() // dynamic dispatching 

La sortie est bien:

SubObj Implementation 
ManObj baseFunc 
Model implementation 

Mais je déteste le casting dans la ligne (self as! ManObj).baseFunc().

En fait, je prévois d'appliquer le protocole Model aux sous-classes de ManObj. (Mais pas toutes les sous-classes de ManObj sont Model bien!) Alors, j'ai essayé de changer Model à:

extension Model where Self: ManObj { 
    func someFunc() { 
     self.baseFunc() // No more casting needed! 
     print("Model implementation") 
    } 
} 

Mais je suis saluèrent avec l'erreur:

list2.someFunc() < - error: 'Model' is not a subtype of 'ManObj'

Ainsi, est-il un moyen pour moi de déclencher Model.someFunc de list2 après que je contraindre Model à where Self: ManObj?

Répondre

0

Créer une classe vide juste pour le type coulée

class ManObj { 
    func baseFunc() { 
     print("ManObj baseFunc") 
    } 
} 

class SubObj: ModelCaster { 
    func someFunc() { 
     print("SubObj Implementation") 
    } 
} 

protocol Model { 
} 

extension Model where Self: ModelCaster { // This is protocol extension 
    func someFunc() { // Protocol extension default implementation 
     print("Model implementation") 
    } 
} 

class ModelCaster: ManObj, Model{ 

} 

let list = SubObj() 
list.someFunc() //SubObj Implementation 

let list2: ModelCaster = SubObj() 
list2.someFunc() //Model implementation