简体   繁体   中英

Protocol conformance check in for loop?

I have two for loops that are trying to do the same thing:

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


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

components is an array of Component objects. UpdateableComponent is a protocol that basically makes a specific Component update on a regular interval. Component has subclasses, such as Timer, Player, Enemy, and other game-related classes, some of which conform to the UpdateableComponent protocol, and some that don't.

The first loop throws the error that Component has no member update, which is true, but the UpdateableComponent protocol does. Why is the where clause not filtering the array? The second loop compiles, but would it give me the desired effect? It's not as clean as the first one though, and I feel they (should) achieve the same effect.

Why is the first loop not a valid option to filter the components array to objects that conform to the UpdateableComponent protocol?

This is because there is no cast in the first loop from Item to UpdatableComponent. The compiler only sees that you're trying to call update on the item which is of type component and doesn't take into account the fact that you're actually only calling it on an UpdateableComponent (we know that we only get UpdateableComponent from the loop filter, but the compiler doesn't). The second loop has a direct cast, so the compiler knows for a fact that if component is not nil, if must be of type UpdatableComponent. The second loop will give you the same desired effect.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM