一.示例

protocol Stackable {
    // 泛型协议,约束条件: Equatable
    associatedtype Element: Equatable
}

// 泛型类,遵守协议
class Stack<E: Equatable>: Stackable {
    typealias Element = E
}

// <> 说明是泛型函数
// T1 T2 遵守协议 Stackable
// 条件约束 where T1.Element == T2.Element 和 T2.Element: Hashable
// 条件约束 where在函数中的位置,函数体大括号的前边
func equal<T1: Stackable, T2: Stackable>(s1: T1, s2: T2)-> Bool
    where T1.Element == T2.Element, T2.Element: Hashable
{
    return false
}

二.泛型约束实际应用示例

1.求和

// 给 Array 添加了类型约束的 Extension。
// 当数组的 Element 遵守了 Numeric 协议的时候, Array 就拥有 sum 这个方法。
extension Array where Element: Numeric {
    func sum() -> Element {
        return reduce(0, +)
    }
}
array.sum() // 15

2.计算某个包含字符串集合中有多少个单词

extension Collection where Element == String {
    func countWords() -> Int {
        return reduce(0) {
            let components = $1.components(separatedBy: .whitespacesAndNewlines)
            return $0 + components.count
        }
    }
}
let array2 = ["sunny","cloudy","apple orange"]
array2.countWords() // 4

3.约束集合类型中的 Element 是 Closure:

extension Sequence where Element ==  () -> Void {
    func callAll() {
        forEach { $0() }
    }
}
let closure1 = {
    print("1")
}
let closure2 = {
    print("2")
}
let array3 = [closure1, closure2]
array3.callAll() 
//1
//2