我有下一个代码:
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:
您可以通过将where关键字紧跟在类型参数列表之后,然后是关联类型的约束或类型与关联类型之间的相等关系来编写where子句。
这是文档中给出的示例:
func allItemsMatch<C1: Container, C2: Container where
C1.ItemType == C2.ItemType, C1.ItemType: Equatable>
(someContainer: C1, _ anotherContainer: C2) -> Bool {
// code
}
请注意,在表示ItemType
类型的关联类型C1
必须符合Equatable
协议时,您使用:
而不是==
,为什么在我的示例中并非如此,我必须使用==
来声明Element
相关联的T.Generator
类型必须符合Flyable
?
使用==
更改:
时,编译器会抱怨:
错误:无法调用&#39; topSpeed&#39;使用类型&#39;([Flyable])&#39;的参数列表注意:期望一个类型为&#39;(T)&#39;
的参数列表
答案 0 :(得分:0)
您可以在不使用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
答案 1 :(得分:0)
我找到了原因here。 where子句具有下一个语法:
conformance-requirement → type-identifier:type-identifier
same-type-requirement → type-identifier==type
因此,当您想声明您的类型参数符合某个协议时,请使用:
。但是,当您希望类型完全属于某种类型时,请使用==
。在我的示例中,我想将Flyable
的集合作为参数。因此,在尝试使用:
时,编译器会抱怨,因为Flyable
不符合Flyable
。 Flyable
是Flyable
,因此我必须使用==
(或者像@Rahul Katariya所做的那样做)