简体   繁体   中英

Comparing type of Generic associated type in Swift

I have the next code:

protocol Flyable {
  var airspeedVelocity: Double { get }
}

func topSpeed<T: CollectionType where T.Generator.Element == Flyable>(collection: T) -> Double {
  return collection.map { $0.airspeedVelocity }.reduce(0) { max($0, $1) }
}

I understood, by reading the Swift Documentation that:

You write a where clause by placing the where keyword immediately after the list of type parameters, followed by constraints for associated types or equality relationships between types and associated types.

This is the example given on the docs:

func allItemsMatch<C1: Container, C2: Container where 
C1.ItemType == C2.ItemType, C1.ItemType: Equatable> 
(someContainer: C1, _ anotherContainer: C2) -> Bool {
    // code
}

Note that when expressing that the associated type ItemType of the C1 type must conform to Equatable protocol you use : and not == , why is that not the case in my example, where I have to use == to state that the Element associated type of T.Generator must conform with Flyable ?

When changing == with : the compiler complains with this:

error: cannot invoke 'topSpeed' with an argument list of type '([Flyable])' note: expected an argument list of type '(T)'

You can achieve this without using Generics.

protocol Flyable {
    var airspeedVelocity: Double { get }
}

func topSpeed(collection: [Flyable]) -> Double {
    return collection.map { $0.airspeedVelocity }.reduce(0) { max($0, $1) }
}

class Airplane: Flyable {

    var airspeedVelocity: Double = 10

}

class Rocket: Flyable {

    var airspeedVelocity: Double = 50

}

topSpeed([Airplane(),Rocket()]) //50

I've found the reason here . The where clause has the next grammar:

conformance-requirement → type-identifier­:­type-identifier­
same-type-requirement → type-identifier­==­type­

So, when you want to state that your type parameter conforms to certain protocol you use : . BUT, when you want your type to be exactly of a certain type, you use == . In my example, I wanted to take as a parameter a collection of Flyable . So, when trying to use : the compiler complained because Flyable doesn't conform to Flyable . Flyable IS Flyable , thus I must use == (or do something like what @Rahul Katariya answered)

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