Swift 入门完全指南:从零开始构建你的第一个 iOS 应用

2 阅读8分钟

前言:Swift 自 2014 年发布以来,已经从一个"苹果专属语言"成长为支持 macOS、Linux、Windows 乃至嵌入式系统的通用编程语言。2024 年 Swift 6 的发布带来了更严格的并发安全模型,而 2025 年 Swift 6.2 的 "Approachable Concurrency" 特性则让并发编程变得更加友好。无论你是编程新手还是从其他语言转来的开发者,Swift 都是一门值得投入的语言。

一、为什么选择 Swift?

1.1 现代语言的基因

Swift 融合了多种编程范式的优点:

  • 安全性优先:类型安全、内存安全(ARC 自动管理)、空值安全(Optional)
  • 性能卓越:接近 C/C++ 的运行效率,远超传统脚本语言
  • 表达力强:语法简洁,支持类型推断,代码可读性极高
  • 开源跨平台:不仅限于苹果生态,也支持 Linux 服务器端和 Windows 开发

1.2 应用场景广泛

表格

场景技术栈说明
iOS/macOS AppSwiftUI / UIKit苹果原生应用开发
命令行工具Swift Package Manager跨平台 CLI 工具
服务端开发Vapor / Hummingbird高性能 Web 服务
嵌入式系统Embedded Swift物联网和底层开发

二、环境搭建:3 分钟上手

2.1 macOS 用户(推荐)

安装 Xcode(App Store 免费下载),它包含了完整的 Swift 工具链。验证安装:

bash

swift --version
# 输出示例:Apple Swift version 6.0

2.2 快速体验:Playground

打开 Xcode → File → New → Playground,这是学习 Swift 的最佳沙盒环境。无需创建完整项目,即可实时看到代码执行结果。

2.3 其他平台

  • Linux: 使用 Swiftly 版本管理器一键安装
  • Windows: 通过官方安装包或 WSL2 配置
  • VS Code: 安装 Swift 扩展获得语法高亮和调试支持

三、Swift 核心语法速览

3.1 变量与常量

swift

// 变量(可变)
var name = "Swift"
name = "Swift 6"  // ✅ 可以修改

// 常量(不可变)—— Swift 鼓励优先使用 let
let version = 6.0
// version = 6.2   // ❌ 编译错误

最佳实践:默认使用 let,只有在确实需要修改时才用 var。这不仅能提升性能,还能减少意外修改带来的 Bug。

3.2 类型系统

Swift 是强类型语言,但支持类型推断:

swift

let implicitInteger = 42        // 推断为 Int
let implicitDouble = 3.14159    // 推断为 Double
let explicitString: String = "Hello"  // 显式声明类型

// 类型转换必须显式进行
let pi = Double(implicitInteger) + implicitDouble

3.3 字符串插值与多行文本

swift

let language = "Swift"
let greeting = "Hello, (language)!"  // "Hello, Swift!"

// 多行字符串(保留格式)
let markdown = """
    # 标题
    - 列表项1
    - 列表项2
    """

3.4 集合类型

swift

// 数组(有序,可重复)
var fruits = ["Apple", "Banana", "Orange"]
fruits.append("Mango")

// 字典(键值对)
var scores = ["Alice": 95, "Bob": 87]
scores["Charlie"] = 92

// 集合(无序,唯一)
var uniqueNumbers: Set = [1, 2, 3, 3, 3]  // 实际存储 {1, 2, 3}

四、Swift 的灵魂特性:Optional

4.1 为什么需要 Optional?

Swift 引入了 Optional(可选类型)来显式处理值可能不存在的情况,从根本上消除了空指针异常。

swift

// ? 表示该变量可能为 nil
var optionalName: String? = nil
optionalName = "Swift"

// ! 强制解包(危险,尽量避免)
// let forced = optionalName!  // 如果为 nil,程序崩溃

// ?? 提供默认值(安全推荐)
let displayName = optionalName ?? "Unknown"

// if let 安全解包(最常用)
if let name = optionalName {
    print("Hello, (name)")  // 只有 name 不为 nil 时才执行
}

// guard let 提前返回(函数内常用)
func greet(_ name: String?) {
    guard let safeName = name else {
        print("No name provided")
        return
    }
    print("Hello, (safeName)")
}

4.2 Optional 链式调用

swift

let user: User? = fetchUser()
let street = user?.address?.street?.uppercased()
// 如果任何一环为 nil,整个表达式返回 nil,不会崩溃

五、控制流:比传统方式更强大

5.1 区间与 for-in

swift

// 闭区间
for index in 1...5 {
    print(index)  // 1, 2, 3, 4, 5
}

// 半开区间
for i in 0..<fruits.count {
    print(fruits[i])
}

// 遍历字典
for (name, score) in scores {
    print("(name): (score)")
}

5.2 switch 的增强

Swift 的 switch 不需要 break,且支持模式匹配:

swift

let point = (2, 0)

switch point {
case (0, 0):
    print("原点")
case (_, 0):  // _ 表示忽略该值
    print("在 x 轴上")
case (0, _):
    print("在 y 轴上")
case (-2...2, -2...2):
    print("在区域内")
default:
    print("在区域外")
}

六、函数与闭包

6.1 函数基础

swift

// 参数标签 + 参数名(让调用更具可读性)
func greet(person name: String, from city: String) -> String {
    return "Hello (name) from (city)!"
}

// 调用时:greet(person: "Tom", from: "Beijing")

// 省略参数标签
func sum(_ a: Int, _ b: Int) -> Int {
    return a + b
}
// 调用时:sum(3, 5)

6.2 闭包(Closure)

闭包是自包含的代码块,类似于其他语言的 Lambda 或匿名函数:

swift

// 排序闭包
let numbers = [5, 3, 8, 1, 2]
let sorted = numbers.sorted { $0 > $1 }  // 降序排列

// 尾随闭包语法(让代码更优雅)
let doubled = numbers.map { number in
    number * 2
}

// 简写参数名
let evens = numbers.filter { $0 % 2 == 0 }

闭包捕获值:

swift

func makeIncrementer(incrementAmount: Int) -> () -> Int {
    var total = 0
    let incrementer: () -> Int = {
        total += incrementAmount
        return total
    }
    return incrementer
}

let incrementByTen = makeIncrementer(incrementAmount: 10)
print(incrementByTen())  // 10
print(incrementByTen())  // 20(闭包捕获并保留了 total 的状态)

七、面向对象:类 vs 结构体

7.1 核心区别

表格

特性结构体 (struct)类 (class)
类型值类型引用类型
继承不支持支持
内存栈分配(高效)堆分配(ARC 管理)
拷贝行为深拷贝(独立副本)浅拷贝(共享引用)
线程安全天然安全(不可变拷贝)需要额外同步

7.2 优先使用结构体

swift

// 定义一个结构体(推荐默认选择)
struct Point {
    var x: Double
    var y: Double
    
    // 结构体自动获得逐一成员构造器
    // init(x: Double, y: Double) 自动生成
}

var pointA = Point(x: 0, y: 0)
var pointB = pointA      // 值拷贝,pointB 是独立副本
pointB.x = 10
print(pointA.x)          // 0(不受影响)

7.3 何时使用类?

swift

// 需要继承、身份标识或共享状态时
class User {
    let id: UUID
    var name: String
    
    init(name: String) {
        self.id = UUID()
        self.name = name
    }
    
    // 析构函数
    deinit {
        print("User (name) is being deallocated")
    }
}

let user1 = User(name: "Alice")
let user2 = user1        // 引用拷贝,指向同一对象
user2.name = "Bob"
print(user1.name)        // "Bob"(共享状态)

八、协议与泛型:Swift 的多态哲学

8.1 协议(Protocol)

协议定义了类型需要实现的接口:

swift

protocol Greetable {
    var name: String { get }
    func greet() -> String
}

// 结构体遵循协议
struct Person: Greetable {
    let name: String
    
    func greet() -> String {
        return "Hi, I'm (name)"
    }
}

// 协议作为类型使用
func welcome(_ greeter: Greetable) {
    print(greeter.greet())
}

8.2 泛型(Generics)

泛型让代码复用且类型安全:

swift

// 泛型函数
func swapValues<T>(_ a: inout T, _ b: inout T) {
    let temp = a
    a = b
    b = temp
}

// 泛型结构体
struct Stack<Element> {
    private var items: [Element] = []
    
    mutating func push(_ item: Element) {
        items.append(item)
    }
    
    mutating func pop() -> Element? {
        return items.popLast()
    }
}

var intStack = Stack<Int>()
intStack.push(10)
intStack.push(20)

8.3 协议扩展:给协议添加默认实现

swift

extension Greetable {
    func greet() -> String {
        return "Hello, my name is (name)"
    }
}

// 现在遵循 Greetable 的类型可以不再实现 greet(),使用默认实现

九、错误处理

Swift 使用 throws / try / catch 进行显式错误处理:

swift

enum NetworkError: Error {
    case badURL
    case noData
    case decodingFailed
}

func fetchData(from urlString: String) throws -> Data {
    guard let url = URL(string: urlString) else {
        throw NetworkError.badURL
    }
    // ... 网络请求逻辑
    return Data()
}

// 调用方式
do {
    let data = try fetchData(from: "https://api.example.com")
    print("获取成功")
} catch NetworkError.badURL {
    print("URL 格式错误")
} catch {
    print("未知错误: (error)")
}

// 可选 try(转换为 Optional)
let optionalData = try? fetchData(from: "invalid-url")  // nil

Swift 6 新特性:类型化抛出(Typed Throws),可以精确指定函数抛出的错误类型:

swift

// Swift 6 中更精确的错误声明
func copyFile() throws(NetworkError) { ... }

十、Swift 6 并发编程入门

10.1 async / await 基础

Swift 原生支持结构化并发,告别回调地狱:

swift

func fetchUser() async throws -> User {
    let (data, _) = try await URLSession.shared.data(from: url)
    let user = try JSONDecoder().decode(User.self, from: data)
    return user
}

// 调用异步函数
Task {
    do {
        let user = try await fetchUser()
        print(user.name)
    } catch {
        print("获取失败")
    }
}

10.2 Actor:线程安全的封装

Actor 是 Swift 中保护可变状态的并发原语:

swift

@MainActor  // 确保在主线程运行(UI 操作必需)
class ViewModel: ObservableObject {
    @Published var users: [User] = []
    
    func loadUsers() async {
        // 自动在主线程执行
        users = try! await fetchAllUsers()
    }
}

10.3 Swift 6.2 的 Approachable Concurrency

Swift 6.2 引入了更友好的并发模型,默认保持单线程,只有在显式引入并发时才启用安全检查。这大幅降低了初学者的门槛,让并发编程不再"令人望而生畏"。


十一、给初学者的小建议

  1. 多用 Playground:不要急于创建完整项目,先用 Playground 验证想法
  2. 拥抱 let:养成优先使用常量的习惯,代码会更安全
  3. 理解 Optional:这是 Swift 最核心的安全特性,彻底搞懂 ?、!、??、if let、guard let
  4. 从 SwiftUI 开始:如果你目标是开发 App,SwiftUI 的学习曲线比 UIKit 平缓得多
  5. 阅读编译器错误:Swift 的编译器提示非常友好,学会从错误信息中学习
  6. 不要跳过基础:直接 copy 代码跑 Demo 看似高效,但扎实的基础才能让你走得更远

结语

Swift 是一门既适合初学者入门,又能支撑大型工程实践的现代化语言。它的设计哲学——安全、快速、表达力强——贯穿在每一个语法细节中。随着 Swift 6 对并发模型的完善和 Swift 6.2 对并发编程的进一步简化,现在正是学习 Swift 的最佳时机。

"The only way to learn a new programming language is by writing programs in it." —— Dennis Ritchie

打开你的 Xcode Playground,写下第一行 print("Hello, Swift!"),你的 Swift 之旅就此开始。🚀