1.1 为什么是 Swift?
Swift 是 Apple 于 2014 年发布的现代编程语言,专为 Apple 生态系统(iOS、macOS、watchOS、tvOS)设计。它吸取了 Objective-C、Rust、Haskell 等语言的精华,在安全性、性能与表达力之间取得了出色的平衡。
Safe(安全)· Fast(高性能)· Expressive(表达力强)。Swift 的类型系统和可选值机制从语言层面消除了大量常见的运行时崩溃。
Swift vs Objective-C
| 特性 | Swift | Objective-C |
|---|---|---|
| 语法 | 简洁现代 | 繁琐,C 风格 |
| 类型安全 | 强类型 + 类型推断 | 弱类型 |
| 可选值 | 语言内置 | 需手动判断 nil |
| 内存管理 | ARC(自动) | ARC(需更多手动干预) |
| 并发 | 原生 async/await | GCD 回调 |
1.2 变量与常量
Swift 使用 var 声明变量(可变),let 声明常量(不可变)。优先使用 let 是 Swift 的编程规范——不需要变化的值应当是常量,这有助于编译器优化并减少意外修改。
// 常量:值确定后不可修改
let appName = "古法编程"
let maxRetries: Int = 3
// 变量:值可以随时修改
var currentScore = 0
currentScore = 100 // ✅ 允许
// appName = "其他" // ❌ 编译错误:cannot assign to 'let'
// 类型推断:Swift 根据初始值自动推断类型
let pi = 3.14159 // 推断为 Double
let greeting = "Hello" // 推断为 String
// 显式类型注解
var temperature: Double = 36.5
var isLoggedIn: Bool = false
Swift 基础类型
| 类型 | 说明 | 示例 |
|---|---|---|
Int | 整数(64位) | 42, -7 |
Double | 双精度浮点数 | 3.14, -0.5 |
Float | 单精度浮点数(较少用) | 3.14 |
Bool | 布尔值 | true, false |
String | 字符串 | "Hello" |
Character | 单个字符 | "A" |
字符串插值
Swift 的字符串插值使用 \(表达式) 语法,非常方便:
let name = "小明"
let age = 25
let message = "我叫 \(name),今年 \(age) 岁"
// "我叫 小明,今年 25 岁"
// 可以嵌入任意表达式
let result = "2 + 3 = \(2 + 3)" // "2 + 3 = 5"
1.3 集合类型
数组(Array)
数组是有序的同类型元素集合,支持重复元素。
// 创建数组
var fruits: [String] = ["苹果", "香蕉", "橙子"]
var numbers = [1, 2, 3, 4, 5] // 类型推断为 [Int]
// 访问与修改
let first = fruits[0] // "苹果"
fruits.append("葡萄") // 追加元素
fruits.insert("草莓", at: 1) // 在索引1插入
fruits.remove(at: 0) // 移除第一个
// 常用属性
fruits.count // 元素个数
fruits.isEmpty // 是否为空
fruits.first // 第一个元素(Optional)
fruits.last // 最后一个元素(Optional)
字典(Dictionary)
字典是无序的键值对集合,键必须唯一且遵循 Hashable 协议。
var scores: [String: Int] = ["Alice": 95, "Bob": 87]
// 访问(返回 Optional,键可能不存在)
let aliceScore = scores["Alice"] // Optional(95)
let carolScore = scores["Carol"] // nil
// 添加/修改
scores["Carol"] = 92
scores["Alice"] = 98 // 修改
// 遍历
for (name, score) in scores {
print("\(name): \(score)")
}
1.4 可选值(Optional)— Swift 最重要的特性
可选值是 Swift 最具代表性的安全特性。它表示"这个值可能存在,也可能不存在"。在 Objective-C 和许多其他语言中,访问不存在的值会导致运行时崩溃;Swift 通过类型系统在编译期就强制开发者处理这种情况。
可选值 Optional<T> 是一个枚举,有两个 case:.some(T) 表示有值,.none 表示无值(nil)。
// 声明可选值:在类型后加 ?
var username: String? = "小明"
var nickname: String? = nil
// ❌ 不能直接使用可选值
// let upper = username.uppercased() // 编译错误
// ✅ 方式1:可选绑定(if let)—— 最常用
if let name = username {
print("用户名:\(name)") // name 是 String,非 Optional
} else {
print("未登录")
}
// ✅ Swift 5.7+ 简化语法
if let username {
print("用户名:\(username)")
}
// ✅ 方式2:guard let —— 适合提前返回
func greet(user: String?) {
guard let user else {
print("请先登录")
return
}
print("你好,\(user)") // 此处 user 已确保非 nil
}
// ✅ 方式3:空合运算符 ?? —— 提供默认值
let displayName = username ?? "游客" // 若 username 为 nil,使用 "游客"
// ✅ 方式4:可选链(Optional Chaining)
let count = username?.count // 若 username 为 nil,count 也为 nil
// ⚠️ 强制解包(!)—— 谨慎使用,nil 时会崩溃
let forced = username! // 确定有值时才用
1.5 控制流
// if-else
let score = 85
if score >= 90 {
print("优秀")
} else if score >= 60 {
print("及格")
} else {
print("不及格")
}
// for-in 循环
for i in 1...5 { print(i) } // 1 2 3 4 5(闭区间)
for i in 1..<5 { print(i) } // 1 2 3 4(半开区间)
for fruit in fruits { print(fruit) } // 遍历数组
// while
var count = 0
while count < 3 {
count += 1
}
// switch —— Swift 中 switch 功能更强大,无需 break
let day = "周一"
switch day {
case "周六", "周日":
print("周末")
case "周一"..."周五":
print("工作日")
default:
print("未知")
}
1.6 函数
Swift 的函数支持参数标签(外部名)和参数名(内部名),调用时语义更清晰。
// 基本函数
func add(_ a: Int, _ b: Int) -> Int {
return a + b
}
add(3, 5) // 8,_ 表示忽略外部标签
// 参数标签:让调用更像自然语言
func greet(person name: String, from city: String) -> String {
return "你好 \(name),来自 \(city)"
}
greet(person: "小明", from: "北京")
// 默认参数值
func log(_ message: String, level: String = "INFO") {
print("[\(level)] \(message)")
}
log("启动完成") // [INFO] 启动完成
log("出错了", level: "ERROR")
// 多返回值(元组)
func minMax(_ array: [Int]) -> (min: Int, max: Int) {
return (array.min()!, array.max()!)
}
let result = minMax([3, 1, 4, 1, 5])
print(result.min, result.max) // 1 5
1.7 闭包(Closure)
闭包是可以在代码中传递和使用的功能块,类似于其他语言中的 Lambda 表达式或匿名函数。在 SwiftUI 中,闭包无处不在。
// 完整闭包语法
let multiply = { (a: Int, b: Int) -> Int in
return a * b
}
multiply(3, 4) // 12
// 类型推断 + 隐式返回(单行)
let add: (Int, Int) -> Int = { $0 + $1 } // $0, $1 是简写参数名
// 作为函数参数(高阶函数)
let numbers = [5, 2, 8, 1, 9, 3]
let sorted = numbers.sorted { $0 < $1 } // [1, 2, 3, 5, 8, 9]
let evens = numbers.filter { $0 % 2 == 0 } // [2, 8]
let doubled = numbers.map { $0 * 2 } // [10, 4, 16, 2, 18, 6]
let sum = numbers.reduce(0) { $0 + $1 } // 28
// 尾随闭包语法:最后一个参数是闭包时,可写在括号外
let result = numbers.sorted { a, b in
a < b
}
1.8 结构体与类
Swift 中两种最重要的自定义类型。结构体(struct)是值类型,赋值时复制;类(class)是引用类型,赋值时共享引用。SwiftUI 大量使用结构体。
赋值时拷贝数据,线程安全,SwiftUI View 均为 struct
赋值时共享同一对象,支持继承,适合需要共享状态的场景
// 结构体(SwiftUI 中首选)
struct Point {
var x: Double
var y: Double
// 计算属性
var distance: Double {
(x * x + y * y).squareRoot()
}
// 方法(结构体方法若修改属性需加 mutating)
mutating func move(dx: Double, dy: Double) {
x += dx
y += dy
}
}
var p1 = Point(x: 3, y: 4) // 自动获得逐一成员初始化器
var p2 = p1 // 值拷贝,p2 是独立副本
p1.move(dx: 1, dy: 0) // p2 不受影响
// 类
class BankAccount {
var balance: Double
init(balance: Double) {
self.balance = balance
}
func deposit(_ amount: Double) {
balance += amount
}
}
let account1 = BankAccount(balance: 1000)
let account2 = account1 // 引用同一对象
account1.deposit(500) // account2.balance 也变为 1500
1.9 协议(Protocol)
协议定义了一组属性和方法的接口契约,遵循协议的类型必须实现这些要求。协议是 Swift 面向协议编程(POP)的核心,也是 SwiftUI 中 View、Identifiable、Codable 等机制的基础。
// 定义协议
protocol Greetable {
var name: String { get }
func greet() -> String
}
// 遵循协议
struct User: Greetable {
let name: String
func greet() -> String { "你好,我是 \(name)" }
}
// Codable:JSON 序列化/反序列化的核心协议
struct Article: Codable, Identifiable {
let id: Int
let title: String
let author: String
}
// JSON 解码
let json = """
{"id": 1, "title": "Swift 入门", "author": "小明"}
""".data(using: .utf8)!
let article = try? JSONDecoder().decode(Article.self, from: json)
1.10 枚举(Enum)
Swift 的枚举功能远比其他语言强大,支持关联值、计算属性和方法。
// 基本枚举
enum Direction {
case north, south, east, west
}
// 关联值(Associated Values)
enum NetworkResult {
case success(data: Data)
case failure(error: Error)
}
func handle(_ result: NetworkResult) {
switch result {
case .success(let data):
print("收到数据:\(data.count) 字节")
case .failure(let error):
print("请求失败:\(error)")
}
}
// Result 类型(标准库内置,等价于上面的枚举)
func fetchData() -> Result<String, Error> {
return .success("数据加载成功")
}
本章学习了 Swift 的核心语法:变量常量、可选值、集合、控制流、函数、闭包、结构体/类/协议/枚举。其中可选值是 Swift 最重要的特性,务必熟练掌握。下一章我们将开始真正的 SwiftUI 之旅。