2017-02-08 1 views
0

J'ai essayé de créer le protocole qui ne peut être mis en œuvre par les classes qui héritent de UIView, quelle fut ma surprise lorsque ce code compile sans erreur (à Swift 3.0):Comment créer la contrainte sur le protocole

protocol TestsProtocol { 
    func test() 
} 

extension TestsProtocol where Self: UIView { } 

class FooClass: TestsProtocol { 

    func test() { 

    } 
} 

Nous peut voir que FooClass n'hérite pas de UIView, en utilisant l'extension de protocole je ne peux pas forcer que seules les classes qui héritent de UIView peuvent l'implémenter. Autant que je m'en souvienne, cela ne serait pas compilé dans Swift 2.1

+0

Je ne peux pas imaginer de raison pour laquelle cela ne serait pas compilé dans Swift 2.1 - les extensions de protocole ne limitent pas les types qui peuvent se conformer à un protocole, ils vous permettent juste d'ajouter des implémentations par défaut. Mais la vraie question est de savoir si un type * peut * répondre à toutes les exigences du protocole, pourquoi * ne devrait-il pas être autorisé à se conformer à moins qu'il ne s'agisse aussi d'un "UIView"? – Hamish

+0

Copie possible de [extension qui ne peut être appliquée qu'à un type de classe donné] (http://stackoverflow.com/questions/41349324/extension-that-can-only-be-applied-on-a-given-class- type) - bien que je ne crois pas que la réponse atteigne * exactement * ce que vous voulez. La réponse est simplement que vous ne pouvez pas restreindre la conformité à un protocole basé sur le type conforme. – Hamish

Répondre

2

Vous ne pouvez pas le faire dans Swift. La syntaxe d'extension fait quelque chose d'autre:

extension TestsProtocol where Self: UIView { 
    func useful() { 
     // do something useful 
    } 
} 

maintenant une classe qui implémente TestsProtocol et est un UIView (ou sous-classe) a également la fonction utile().