9
votes

Tablier et où en boucle

J'ai le scénario suivant:

for b in objects where b is B // <- compiles, but b is typed as A, not B
for b: B in objects where b is B // <- doesn't compile
for b in objects as! [B] where b is B // <- I get a warning that "is" will always be true


0 commentaires

3 Réponses :


0
votes

Je ne suis pas certain que cela répond à votre cas - parce que vous avez déjà quelque chose de similaire - et je ne comprends pas entièrement ce que vous n'aimez pas sur votre version. Cependant, cela fonctionne dans SWIFT 2:

var objectArray: [AnyObject] = []
// contains a mix of objects of the following 3 classes


class class01: protocolA {
}
class class02: protocolA, protocolB {
    func test() -> String {
    // required to conform to protocolB
    return "hello"
    }
}
class class03: protocolA, protocolB, protocolC {
    func test() -> String {
    // required to conform to protocolB
    return "hello"
    }
}

protocol protocolA {
}
protocol protocolB: protocolA {
    func test() -> String
}
protocol protocolC: protocolA {
}


5 commentaires

Si protocole définirait une fonction test () , vous ne pourriez pas l'appeler sur objet dans votre itération sans tabler Objet à protocole , car objet est de type anyObject , non de type protocole .


Dans le code mis à jour, si vous essayez d'appeler impression (objet.test ()) dans la boucle que vous avez commentée, vous obtiendrez une erreur ('' anyObject 'n'a pas de membre nommé' test () ').


Cela fonctionne absolument bien dans Xcode7. Y compris impression (objet) . C'était seulement commenté parce que c'était un par exemple.


Bien sûr impression (objet) fonctionne, car impression () prend un paramètre anyObject . impression (objet.test ()) ne signifie pas, car test () n'est pas défini sur anyobject . Le point est que vous ne pouvez pas appeler test () sur objet , pas que vous ne pouvez pas imprimer objet , et vous n'êtes jamais appeler test () dans votre exemple.


Enfin je comprends. Merci de persévérer avec moi.



8
votes

Il y a aussi pour étui code> (presque idem code> code> comme dans code> commutateur code> instructions) afin de ressembler à ceci:

for case let b as protocol<B, C> in objects {
  // use b which is now of type protocol<B, C>
}


0 commentaires

2
votes

comme? Le sous-type code> et ses variantes sont une odeur de code. Les autres réponses ici vous aideront à accomplir ce que vous voulez, mais je voulais vous suggérer de déplacer cette logique à partir du pour code> en boucle au protocole (si c'est possible).

Par exemple, considérons une Shape Code> Protocole: P>

for shape in shapes {
    shape.draw()
    shape.executeSomeSpecialOperation()
}


4 commentaires

Cela suppose que la méthode est logique pour toutes les formes . Que feriez-vous par exemple si vous vouliez calculer le rayon moyen de tous les cercles des formes ?


Je ne stockerais pas les types hétérogènes dans un tableau si je dois effectuer des opérations qui comptent sur homogénie. Vous pouvez, par exemple, avoir un tableau distinct RADY, et faire des formes une propriété calculée.


Alors, chaque fois que vous avez besoin d'une liste de toutes formes, un nouveau tableau serait instancié?


Oui, bien qu'il soit facile de le mettre en cache s'il y a des problèmes de performance.