下面我将系统梳理 Swift 6 泛型的核心语法、进阶用法,并给出练习题详解。
一、泛型基础
1. 泛型函数
泛型函数能用任意类型参数调用,且类型安全。
func makeArray<Item>(repeating item: Item, numberOfTimes: Int) -> [Item] {
var result: [Item] = []
for _ in 0..<numberOfTimes {
result.append(item)
}
return result
}
makeArray(repeating: "knock", numberOfTimes: 4) // ["knock", "knock", "knock", "knock"]
- 尖括号
<Item>
声明泛型参数。
- Swift 会自动根据调用的参数推断
Item
的类型。
2. 泛型类型
不仅函数,结构体/枚举/类都可以是泛型:
enum OptionalValue<Wrapped> {
case none
case some(Wrapped)
}
var possibleInteger: OptionalValue<Int> = .none
possibleInteger = .some(100)
<Wrapped>
是泛型参数,OptionalValue
可用于任意类型。
二、泛型约束
泛型约束可以:
- 限定泛型参数必须继承某个类
- 或遵循某协议
- 或彼此类型关系
两种等价写法
<T: Equatable>
<T> where T: Equatable
3. 泛型约束与 where 子句
func anyCommonElements<T: Sequence, U: Sequence>(_ lhs: T, _ rhs: U) -> Bool
where T.Element: Equatable, T.Element == U.Element
{
for lhsItem in lhs {
for rhsItem in rhs {
if lhsItem == rhsItem {
return true
}
}
}
return false
}
anyCommonElements([1, 2, 3], [3]) // true
<T: Sequence, U: Sequence>
:两个泛型参数都要是序列类型。
where T.Element: Equatable, T.Element == U.Element
:
三、练习题详解
题目:
修改 anyCommonElements(:🙂 函数,使其返回一个数组,该数组包含任意两个序列中共有的元素。
解析思路
- 返回值改成
[T.Element]
- 用 Set 优化查找效率,防止重复元素
完整解答
func commonElements<T: Sequence, U: Sequence>(_ lhs: T, _ rhs: U) -> [T.Element]
where T.Element: Equatable, T.Element == U.Element
{
var result: [T.Element] = []
for lhsItem in lhs {
for rhsItem in rhs {
if lhsItem == rhsItem {
// 避免重复添加
if !result.contains(lhsItem) {
result.append(lhsItem)
}
}
}
}
return result
}
print(commonElements([1, 2, 3, 3], [3, 4, 1])) // [1, 3]
用 Set 优化效率:
func commonElements<T: Sequence, U: Sequence>(_ lhs: T, _ rhs: U) -> [T.Element]
where T.Element: Hashable, T.Element == U.Element
{
let rhsSet = Set(rhs)
var result: Set<T.Element> = []
for lhsItem in lhs {
if rhsSet.contains(lhsItem) {
result.insert(lhsItem)
}
}
return Array(result)
}
print(commonElements([1, 2, 3, 3], [3, 4, 1])) // [1, 3]
注意此时要加 where T.Element: Hashable
,因为 Set 需要元素可哈希。
四、泛型约束写法对比
<T: Equatable>
和 <T> where T: Equatable>
是等价的,可按实际代码风格选择。
五、泛型的常见应用场景
- 标准库集合类型(Array、Set、Dictionary)
- 可选类型(Optional<T>)
- 通用算法(排序、查找、过滤等)
- 网络、数据层的通用容器
六、总结
- 用尖括号声明泛型:
<T>
- 可为函数、类型、方法添加泛型
- 用冒号或 where 指定泛型约束
- 泛型让代码更通用、安全、易维护