Swift扩展与泛型编程全面解析
立即解锁
发布时间: 2025-09-12 01:52:38 阅读量: 9 订阅数: 29 AIGC 


Swift编程实战精要
### Swift 扩展与泛型编程全面解析
#### 1. 扩展(Extensions)
扩展是一种极其灵活的工具,可用于增强代码的组织性,并为现有类型添加有用的行为。需要注意的是,扩展虽然主要用于添加新功能,但有时也可通过实现类型中已有的方法或计算属性来替换现有功能。不过这与在子类中重写方法不同,是一个高级主题,实用性有限且存在固有风险。
此外,还给出了两个挑战:
- **青铜挑战**:将 `Department` 类型对 `CustomStringConvertible` 协议的遵循移至扩展中。
- **白银挑战**:为 `Int` 类型添加一个嵌套枚举,包含 `even` 和 `odd` 两个 case,并为 `Int` 类型添加一个该枚举类型的属性,以正确报告整数是偶数还是奇数。
#### 2. 泛型(Generics)
在之前介绍可选类型和集合类型时,我们简单展示过它们的“长格式”语法,例如 `Optional<String>`、`Array<String>`、`Dictionary<String>` 和 `Set<String>`。大多数这类类型都有更常用的简写语法,如 `String?` 或 `[String]`。
`Optional` 和 `Array` 等集合类型被称为泛型类型,因为它们设计为可与任何类型一起工作(有一些限制)。尖括号是泛型语法,可用于指定泛型类型要处理的具体类型。
##### 2.1 泛型数据结构
我们以创建一个泛型栈为例来介绍泛型数据结构。栈是一种后进先出(LIFO)的数据结构,支持两个基本操作:`push`(将元素压入栈)和 `pop`(从栈中弹出最近压入的元素)。
首先,创建一个仅存储整数的 `Stack` 结构体:
```swift
import Cocoa
var str = "Hello, playground"
struct Stack {
var items = [Int]()
mutating func push(_ newItem: Int) {
items.append(newItem)
}
mutating func pop() -> Int? {
guard !items.isEmpty else { return nil }
return items.removeLast()
}
}
```
创建 `Stack` 实例并测试:
```swift
var intStack = Stack()
intStack.push(1)
intStack.push(2)
print(String(describing: intStack.pop()))
print(String(describing: intStack.pop()))
print(String(describing: intStack.pop()))
```
输出结果为:
```
Optional(2)
Optional(1)
nil
```
为了让 `Stack` 更通用,将其修改为泛型数据结构:
```swift
struct Stack<Element> {
var items = [Element]()
mutating func push(_ newItem: Element) {
items.append(newItem)
}
mutating func pop() -> Element? {
guard !items.isEmpty else { return nil }
return items.removeLast()
}
}
```
修改后,在实例化 `Stack` 时需要指定具体类型,否则会出现编译错误:
```swift
var intStack = Stack<Int>()
var stringStack = Stack<String>()
stringStack.push("this is a string")
stringStack.push("another string")
print(String(describing: stringStack.pop()))
```
需要注意的是,`intStack` 和 `stringStack` 虽然都是 `Stack` 实例,但它们的类型不同,`intStack` 是 `Stack<Int>`,`stringStack` 是 `Stack<String>`。
##### 2.2 泛型函数和方法
以 `map(_:)` 方法为例,我们可以自己实现一个类似的泛型函数 `myMap(_:_:)`:
```swift
func myMap<T,U>(_ items: [T], _ txform: (T) -> (U)) -> [U] {
var result = [U]()
for item in items {
result.append(txform(item))
}
return result
}
```
使用 `myMap` 函数将字符串数组映射为其长度的整数数组:
```swift
let strings = ["one", "two", "three"]
let stringLengths = myMap(strings) { $0.count }
print(stringLengths)
```
输出结果为:
```
[3, 3, 5]
```
我们还可以为 `Stack` 结构体添加一个泛型方法 `map(_:)`:
```swift
struct Stack<Element> {
var items = [Element]()
mutating func push(_ newItem: Element) {
items.append(newItem)
}
mutating func pop() -> Element? {
guard !items.isEmpty else { return nil }
return items.removeLast()
}
func map<U>(_ txform: (Element) -> U) -> Stack<U> {
var mappedItems = [U]()
for item in items {
mappedItems.append(txform(item))
}
return Stack<U>(items: mappedItems)
}
}
```
测试 `Stack` 的 `map` 方法:
```swift
var intStack = Stack<Int>()
intStack.push(1)
intS
```
0
0
复制全文
相关推荐









