当你使用泛型时,可以为没有独立类型约束的声明添加 where
分句。例如,你可以使用 where
分句为泛型添加下标,或为扩展方法添加泛型约束。Container
结构体是个泛型,下面的例子通过 where
分句让新的方法声明其调用所需要满足的类型约束。
extension Container {
func average() -> Double where Item == Int {
var sum = 0.0
for index in 0..<count {
sum += Double(self[index])
}
return sum / Double(count)
}
func endsWith(_ item: Item) -> Bool where Item: Equatable {
return count >= 1 && self[count-1] == item
}
}
let numbers = [1260, 1200, 98, 37]
print(numbers.average())
// 输出 "648.75"
print(numbers.endsWith(37))
// 输出 "true"
例子中,当 Item
是整型时为 Container
添加 average()
方法,当 Item
遵循 Equatable
时添加 endsWith(_:)
方法。两个方法都通过 where
分句对 Container
中定义的泛型 Item
进行了约束。
如果不使用包含上下文关系的 where
分句,需要写两个扩展,并为每个扩展分别加上 where
分句。下面的例子和上面的具有相同效果。
extension Container where Item == Int {
func average() -> Double {
var sum = 0.0
for index in 0..<count {
sum += Double(self[index])
}
return sum / Double(count)
}
}
extension Container where Item: Equatable {
func endsWith(_ item: Item) -> Bool {
return count >= 1 && self[count-1] == item
}
}
在包含上下文关系的 where
分句的例子中,由于每个方法的 where
分句各自声明了需要满足的条件,因此 average()
和 endsWith(_:)
的实现能放在同一个扩展里。而将 where
分句放在扩展进行声明也能起到同样的效果,但每一个扩展只能有一个必备条件。