2016-07-20 8 views
0

Ich habe zwei for-Schleifen, die die gleiche Sache zu tun versuchen:Protokollkonformitätsprüfung für for-Schleife?

for item in components where item is UpdateableComponent 
{ 
    item.update() 
} 


for item in components 
{ 
    if let component = item as? UpdateableComponent 
    { 
     component.update() 
    } 
} 

components ein Array von Component Objekten. UpdateableComponent ist ein Protokoll, das grundsätzlich ein spezifisches Component Update in regelmäßigen Abständen erstellt. Component hat Unterklassen wie Timer, Player, Enemy und andere spielbezogene Klassen, von denen einige dem Protokoll UpdateableComponent entsprechen und andere nicht.

Die erste Schleife löst den Fehler aus, Component hat keine Mitglied-Update, das stimmt, aber das UpdateableComponent Protokoll tut. Warum filtert die Where-Klausel das Array nicht? Die zweite Schleife kompiliert, aber würde es mir den gewünschten Effekt geben? Es ist nicht so sauber wie das erste, und ich fühle, dass sie den gleichen Effekt erzielen (sollten).

Warum ist die erste Schleife keine gültige Option zum Filtern des components Arrays auf Objekte, die dem UpdateableComponent Protokoll entsprechen?

Antwort

1

Dies liegt daran, dass in der ersten Schleife von Item zu UpdatableComponent kein Cast vorliegt. Der Compiler erkennt nur, dass Sie versuchen, update für das Element aufzurufen, das vom Typ component ist, und berücksichtigt nicht die Tatsache, dass Sie es tatsächlich nur für eine UpdateableComponent aufrufen (wir wissen, dass wir UpdateableComponent nur vom Loop-Filter, aber der Compiler nicht). Die zweite Schleife hat eine direkte Umwandlung, daher weiß der Compiler, dass, wenn die Komponente nicht null ist, if vom Typ UpdatableComponent sein muss. Die zweite Schleife gibt Ihnen den gleichen gewünschten Effekt.

+0

In der ersten Schleife dann, wäre das akzeptabel? (Element als! UpdateableComponent) .update (dt) –

+0

Ja ich glaube es würde. Eine explizite Besetzung sollte in Ordnung sein, da Sie zuerst filtern – Amloelxer