面试题答案
一键面试泛型约束概念
泛型约束用于限制泛型类型参数必须符合特定的条件。比如可以限制类型参数必须是某个类的子类,或者必须遵循某个协议。通过泛型约束,可以确保在泛型代码中对类型参数进行的操作是有效的。例如,当我们希望一个泛型类型能够进行比较操作时,可以约束该泛型类型遵循 Equatable
协议。
关联类型概念
关联类型为协议中的某个类型提供一个占位符名称。协议的实现者可以指定实际的类型来替换这个占位符。关联类型通常用于定义一些需要在协议实现中具体确定类型的场景,比如在 Collection
协议中,Index
就是一个关联类型,不同的集合类型(如数组、字典)会有不同的索引类型。
区别
- 泛型约束:是对泛型类型参数的限制条件,在定义泛型函数或类型时指定,用于确保类型参数具有某些特性。
- 关联类型:主要在协议中使用,为协议中用到的类型提供一个抽象的名称,由协议的实现者来具体指定实际类型。
示例代码
// 定义一个协议,包含关联类型
protocol Container {
associatedtype Item
mutating func append(_ item: Item)
var count: Int { get }
subscript(i: Int) -> Item { get }
}
// 泛型函数,使用泛型约束和关联类型
func printContainer<T: Container>(_ container: inout T) where T.Item: CustomStringConvertible {
for i in 0..<container.count {
print(container[i])
}
}
// 数组遵循 Container 协议
extension Array: Container {}
// 使用示例
var numbers: [Int] = [1, 2, 3]
printContainer(&numbers)
在上述代码中,Container
协议定义了关联类型 Item
。printContainer
函数是一个泛型函数,它的类型参数 T
受限于 Container
协议,并且进一步约束了 T.Item
必须遵循 CustomStringConvertible
协议,这样就能确保在函数中可以安全地打印容器中的元素。