在 Swift 中,where 关键字用于添加额外的约束条件,增强代码的精确性和安全性。以下是常见应用场景及示例代码:
1. 泛型类型约束
为泛型类型添加协议或类型要求:
func process<T>(_ value: T) where T: Equatable {
if value == value { // 可用 == 操作符
print("值相等")
}
}
2. 协议扩展条件约束
为特定条件下的协议提供默认实现:
extension Collection where Element: Numeric {
func sum() -> Element {
return reduce(0, +)
}
}
let numbers = [1, 2, 3]
print(numbers.sum()) // 输出:6
3. 循环中的条件过滤
在 for-in 循环中动态过滤元素:
let scores = [75, 42, 98, 53]
for score in scores where score >= 60 {
print("及格分数:\(score)")
}
// 输出:75, 98
4. Switch 语句的额外条件
在 switch 的 case 中添加逻辑判断:
let point = (2, 2)
switch point {
case (let x, let y) where x == y:
print("点在 y = x 对角线上")
default:
break
}
// 输出:点在 y = x 对角线上
5. 关联类型的协议约束
约束协议关联类型的类型要求:
protocol Container {
associatedtype Item
func add(_ item: Item)
}
extension Container where Item: Equatable {
func contains(_ target: Item) -> Bool {
// 实现比较逻辑(此处简化)
return true
}
}
6. 类型别名约束
为类型别名添加泛型约束:
typealias NumericDictionary<Value> = [String: Value]
where Value: Numeric
let dict: NumericDictionary<Int> = ["age": 30]
7. 错误处理的模式匹配
在 catch 中捕获特定错误:
enum NetworkError: Error {
case timeout(duration: Int)
case invalidResponse(code: Int)
}
do {
throw NetworkError.timeout(duration: 30)
} catch NetworkError.timeout(let duration) where duration > 20 {
print("严重超时:\(duration)秒")
} catch {
print("其他错误")
}
// 输出:严重超时:30秒
8. 可选绑定的条件检查
在 if let 或 guard let 中添加额外条件:
func loadImage(name: String?) {
guard let filename = name,
!filename.isEmpty else {
return
}
print("加载图片: \(filename)")
}
loadImage(name: "avatar.png") // 成功执行
loadImage(name: "") // 被 guard 拦截
关键点总结:
| 场景 | 作用 | 典型代码模式 |
|---|---|---|
| 泛型函数/类型 | 添加类型约束 | func foo<T>() where T: Protocol |
| 协议扩展 | 限定扩展生效范围 | extension Proto where T: Type |
| 循环控制 | 动态过滤元素 | for x in array where condition |
| Switch 语句 | 增强模式匹配 | case pattern where condition |
| 错误处理 | 精确捕获错误 | catch error where condition |
| 可选绑定 | 绑定后立即检查条件 | if let x = opt where x > 0 |
通过合理使用 where,可以显著提升代码的类型安全性和表达力,减少冗余的类型检查逻辑。