Chapter 01

Swift 语言基础

掌握 Swift 的类型系统、可选值、函数与闭包,为 SwiftUI 开发打下坚实基础

1.1 为什么是 Swift?

Swift 是 Apple 于 2014 年发布的现代编程语言,专为 Apple 生态系统(iOS、macOS、watchOS、tvOS)设计。它吸取了 Objective-C、Rust、Haskell 等语言的精华,在安全性、性能与表达力之间取得了出色的平衡。

ℹ️
Swift 的核心设计哲学

Safe(安全)· Fast(高性能)· Expressive(表达力强)。Swift 的类型系统和可选值机制从语言层面消除了大量常见的运行时崩溃。

Swift vs Objective-C

特性SwiftObjective-C
语法简洁现代繁琐,C 风格
类型安全强类型 + 类型推断弱类型
可选值语言内置需手动判断 nil
内存管理ARC(自动)ARC(需更多手动干预)
并发原生 async/awaitGCD 回调

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 大量使用结构体。

📦
Struct(值类型)

赋值时拷贝数据,线程安全,SwiftUI View 均为 struct

🔗
Class(引用类型)

赋值时共享同一对象,支持继承,适合需要共享状态的场景

// 结构体(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 中 ViewIdentifiableCodable 等机制的基础。

// 定义协议
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 之旅。