大家好,我是程序员柏风,AI 最全的 Vibecoding 学习地图 http://coderoadmap.cn 作者。
函数与闭包
Swift 函数是一等公民;闭包(Closure)可捕获上下文,是 SwiftUI 事件处理与异步编程的基础。对照 /roadmaps/swift-ui「函数与闭包」节点。
学习目标
- 定义带参数标签、默认值与可变参数的函数
- 理解闭包语法与 Trailing Closure
- 掌握
@escaping与捕获列表[weak self] - 编写
async函数并在 SwiftUI 中调用
核心概念
函数定义与参数
func formatDuration(minutes: Int, suffix: String = "分钟") -> String {
return "\(minutes) \(suffix)"
}
func sum(_ numbers: Int...) -> Int {
numbers.reduce(0, +)
}
// 多返回值(元组)
func parseLesson(_ raw: String) -> (id: Int, title: String)? {
let parts = raw.split(separator: "|")
guard parts.count == 2, let id = Int(parts[0]) else { return nil }
return (id, String(parts[1]))
}
外部参数名提升可读性:formatDuration(minutes: 35);_ 省略外部标签。
闭包与 Trailing Closure
var lessons = ["语法", "控制流", "闭包"]
// 完整闭包
let sorted = lessons.sorted(by: { (a, b) -> Bool in
a.count < b.count
})
// Trailing Closure:最后一个闭包参数可写在括号外
let sorted2 = lessons.sorted { $0.count < $1.count }
// SwiftUI 中常见
Button("排序") {
lessons.sort { $0.count < $1.count }
}
$0、$1 是闭包参数简写;SwiftUI 的 .onTapGesture { }、.task { } 均使用 Trailing Closure。
async 函数
struct Lesson: Decodable {
let id: Int
let title: String
}
func fetchLesson(id: Int) async throws -> Lesson {
try await Task.sleep(nanoseconds: 300_000_000)
return Lesson(id: id, title: "课时 \(id)")
}
struct LessonLoaderView: View {
@State private var lesson: Lesson?
@State private var isLoading = false
var body: some View {
VStack(spacing: 16) {
if isLoading {
ProgressView()
} else if let lesson {
Text(lesson.title).font(.title2)
}
Button("加载") {
Task {
isLoading = true
defer { isLoading = false }
lesson = try? await fetchLesson(id: 1)
}
}
}
.padding()
}
}
async throws 函数用 try await 调用;SwiftUI 中用 Task { } 启动异步任务,.task 修饰符在视图出现时自动执行。
与 React/SwiftUI 对照
| Swift | React | SwiftUI |
|---|---|---|
| 函数 | 普通函数 / 箭头函数 | ViewModel 方法 |
| Trailing Closure | 回调 props onClick={() =>} | .onTapGesture { } |
{ $0 in ... } | (x) => ... | sorted { $0 < $1 } |
@escaping | 异步回调存 ref | 网络 completion |
async/await | async/await | .task { await load() } |
Task { } | useEffect 内 async IIFE | 按钮触发的异步 |
React 的 useCallback 缓存闭包;SwiftUI 中闭包通常随 View 重建,复杂逻辑应放入 ViewModel。
练习
- 写
filterLessons(_:completed:)高阶函数,接受闭包 predicate - 用 Trailing Closure 实现
.map提取 lesson 标题数组 - 编写
async throws模拟网络请求,在 SwiftUI 按钮中触发 - 对比 React
useEffect与 SwiftUI.task生命周期
小结
闭包无处不在 + Trailing Closure 简化语法 + async 驱动 SwiftUI 加载。 下一课结构体、类与协议。见 swift-ui-essentials。