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
}
}
_ "... 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
@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. –
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