2016-04-13 64 views
0

比較通用相關類型的I型具有下一個代碼:在夫特

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) } 
} 

我理解,通過閱讀Swift Documentation在於:

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.

這是關於文檔中給出的示例:

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

請注意,當表示的關聯類型類型必須符合Equatable協議,您使用的是:而不是==,爲什麼在我的示例中不是這種情況,在那裏我必須使用==來說明的關聯類型必須符合Flyable

:編譯器改變==抱怨這一點:

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

回答

0

我找到原因here。 where子句有下一個語法:

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

所以,當你想指出你的類型參數符合某些協議使用:。但是,如果您希望自己的類型完全屬於某種類型,則可以使用==。在我的例子中,我想以Flyable的集合作爲參數。因此,當試圖使用:時,編譯器抱怨,因爲Flyable不符合FlyableFlyable IS Flyable,所以我必須用==(或像做什麼@Rahul Katariya回答)

0

你可以做到這一點,而無需使用泛型。

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 
+0

你應該使用maxElement()方法,而不是減少'回報collection.map {$ 0.airspeedVelocity} .maxElement()? 0' –

+0

謝謝。我仍然想知道爲什麼我必須使用==而不是:在我的例子中,雖然 – bitsoverflow

+0

或'return collection.maxElement({$ 0.0.airspeedVelocity <$ 0.1.airspeedVelocity})?。airspeedVelocity ?? 0' –