2016-10-30 1 views
2

J'essaie de définir un appareil de test conforme à Equatable afin que je puisse vérifier une fonction qui prend un protocole fonctionne comme prévu. J'ai essayé 3 permutations différentes.Pourquoi est-ce que je ne peux qu'implémenter Equatable dans une extension

import XCTest 
import MyProtocol 

struct TestFixture { 
    let identifier: String 
    init(identifier: String) { 
     self.identifier = identifier 
    } 
} 

extension TestFixture: MyProtocol { 
    func myProtocolFunc() {} 
} 

extension TestFixture: Equatable { 
    static func ==(lhs: TestFixture, rhs: TestFixture) { 
     return lhs.identifier == rhs.identifier 
    } 
} 

class TestCase: XCTestCase { 
    func testSomething() { 
     // do something that requires a MyProtocol object 
    } 
} 

Cela fonctionne très bien. Cependant, je voudrais convertir TestFixture dans une définition imbriquée, donc j'essayer:

import XCTest 
import MyProtocol 

class TestCase: XCTestCase { 
    func testSomething() { 

     struct TestFixture { 
      let identifier: String 
      init(identifier: String) { 
       self.identifier = identifier 
      } 
     } 

     extension TestFixture: MyProtocol { 
      func myProtocolFunc() {} 
     } 

     extension TestFixture: Equatable { 
      static func ==(lhs: TestFixture, rhs: TestFixture) { 
       return lhs.identifier == rhs.identifier 
      } 
     } 

     // do something that requires a MyProtocol object 
    } 
} 

À ce stade, je reçois une erreur de compilation sur les deux extension déclarations:

Déclaration est valable uniquement à l'étendue du fichier

Ok, donc je suppose que je ne suis pas censé implémenter des extensions sur des définitions imbriquées. Je vais donc mettre en œuvre tous les protocoles sur la déclaration initiale:

import XCTest 
import MyProtocol 

class TestCase: XCTestCase { 
    func testSomething() { 

     struct TestFixture: MyProtocol, Equatable { 
      let identifier: String 
      init(identifier: String) { 
       self.identifier = identifier 
      } 

      func myProtocolFunc() {} 

      static func ==(lhs: TestFixture, rhs: TestFixture) { 
       return lhs.identifier == rhs.identifier 
      } 
     } 

     // do something that requires a MyProtocol object 
    } 
} 

Et maintenant, je reçois l'erreur du compilateur

Protocole « assimilables » ne peut être utilisé comme une contrainte générique parce qu'il a auto ou les exigences de type associé

ma question est: pourquoi le compilateur ne se plaignent de Equatable ayant des exigences de type associé lorsque je mets en œuvre dans la déclaration initiale d'une struct? Et pourquoi ne puis-je pas définir des extensions dans des types imbriqués? Je veux juste comprendre pourquoi le compilateur fait ces choses.


Fournir un peu plus de contexte, ce que je suis en train de tester ici est qu'une classe correctement un objet ajoute MyProtocol à un tableau:

class MyClass { 
    var elements: [MyProtocol] { 
     return _elements 
    } 
    private var _elements: [MyProtocol] = [] 
    func add(_ element: MyProtocol) { 
     // I'm testing this function 
    } 
} 
+0

_ "... pourquoi le compilateur ne se plaint-il que" Equatable "ayant des exigences de type associées quand je l'implémente dans la déclaration initiale d'une structure?" _: Il n'y a pas de problème de conformité à Equatable dans la déclaration initiale de quelque structure Le problème ici semble provenir du fait que ce type est déclaré _dans le cadre d'une fonction_ (que je, tbh, ne savais même pas légale). Notez qu'il n'y a pas de problème si vous utilisez simplement des types imbriqués (mais omettez les déclarer dans une portée de fonction). – dfri

+0

@dfri merci, il semble que vous avez raison. Si je déplace la déclaration hors de la portée de la fonction et dans la portée de la classe, elle se compile bien. J'ai utilisé les définitions de classe en fonction pour les appareils de test parce que c'est très utile dans ce but, mais je dois pousser le compilateur un peu trop loin. –

+0

Tbh, ce comportement semble un peu bogué: nous ne pouvons pas nous conformer à un type de protocole homogène ('' '' '' '' '' '' '' '' '' '' '' '' '''''''''''' '' '' '' '' '' '' '' '' ' Cela semble ambigu, car je crois, à mon avis, que nous ne pourrions pas déclarer le type dans les blocs fonctionnels _à tout, ou être en mesure de déclarer des types comme dans les autres blocs, y compris les types qui se conforment à un homogène. protocole comme spécifié à la déclaration du type.Cela vaut peut-être la peine de déposer un rapport de bogue, à moins que quelqu'un d'autre ne puisse expliquer cette divergence. – dfri

Répondre

0

Cela semble être un bug avec le Compilateur rapide. La solution actuelle consiste à déclarer la structure en dehors de la portée de la fonction.

Un problème a été ouvert: SR-3092.