2016-07-20 6 views
0

У меня есть два для петель, которые пытаются делать то же самое:Проверка соответствия протокола для цикла?

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


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

components является массивом Component объектов. UpdateableComponent - это протокол, который в основном делает определенное обновление Component на регулярном интервале. Component имеет подклассы, такие как Timer, Player, Enemy и другие связанные с игрой классы, некоторые из которых соответствуют протоколу UpdateableComponent, а некоторые - нет.

Первый цикл выдает ошибку, что Component не имеет обновления для членов, это правда, но протокол UpdateableComponent. Почему предложение where не фильтрует массив? Второй цикл компилируется, но даст ли он желаемый эффект? Это не так чисто, как первое, но я чувствую, что они (должны) достичь такого же эффекта.

Почему первый цикл не является допустимым параметром для фильтрации массива components объектам, которые соответствуют протоколу UpdateableComponent?

ответ

1

Это связано с тем, что в первом цикле нет элементов в элементе Item to UpdatableComponent. Компилятор видит только, что вы пытаетесь вызвать обновление элемента, который имеет компонент типа, и не учитывает тот факт, что вы на самом деле вызываете его только на UpdateableComponent (мы знаем, что мы получаем только UpdateableComponent из петлевого фильтра, но компилятор этого не делает). Во втором цикле есть прямая трансляция, поэтому компилятор знает, что если компонент не равен nil, то должен быть типа UpdatableComponent. Второй цикл даст вам тот же желаемый эффект.

+0

В первом цикле тогда это было бы приемлемо? (item as! UpdateableComponent) .update (dt) –

+0

Да, я верю, что так будет. Явное приведение должно быть в порядке, поскольку вы сначала фильтруете – Amloelxer

Смежные вопросы