Skip to content

Swift Cheatsheet

变量和常量

swift
var name = "骚气老搭子"   // var 定义变量
let age = 18             // let 定义常量

var score: Int = 100         // 整数类型 显式声明类型
var username: String = "宝"  // 字符串类型
var pi: Double = 3.14        // 小数(浮点数)类型
var isLogin: Bool = true     // 布尔值类型(true/false)

print("Hello Swift!")                // 输出普通字符串
print("你好,\(username),得分是 \(score)")  // 用 \() 插入变量,字符串拼接 字符串插值

var level = 1
level = 2  // OK,因为 level 是 var 定义的变量

let city = "北京"
// city = "上海"  // ❌ 报错,let 定义的常量不能改
  • 自动类型推断
  • 强类型语言

数据结构

Array 数组

swift
// 创建数组
var fruits = ["苹果", "香蕉", "橙子"]

// 访问数组元素(索引从 0 开始)
print(fruits[0])  // 输出:苹果

// 修改、添加、删除
fruits[1] = "芒果"     // 改变第二个元素
fruits.append("榴莲")  // 添加一个元素
fruits.remove(at: 0)   // 删除第一个元素

// 创建空数组
var numbers: [Int] = []        // 明确声明类型为空数组
var names = [String]()         // 另一种写法
  • 数组里装的是同一类型的数据,按顺序存放
  • 有序的元素集合
  • append() 是在数组最后加一个;remove(at:) 是删指定位置的

Dictionary 字典

swift
// 创建字典
var user: [String: String] = [
    "name": "张三",
    "city": "上海"
]

// 访问和修改值
print(user["name"]!)       // 输出:张三
user["city"] = "北京"       // 修改城市
user["age"] = "25"         // 添加新键值

//  删除键值对
user.removeValue(forKey: "age")

// 创建空字典
var settings: [String: Bool] = [:]
  • 键值对形式的容器
  • 注意:user["name"] 的结果是一个 可选值(Optional),加 ! 是强制解包(后面讲 Optional 会细讲)

Set 集合

swift
// 创建集合
var colors: Set<String> = ["红", "绿", "蓝"]

// 添加和删除元素
colors.insert("黄")      // 添加一个元素
colors.remove("绿")      // 删除一个元素

// 判断是否包含某个元素
if colors.contains("红") {
    print("有红色")
}

// 集合的操作(交集、并集、差集)
let a: Set = [1, 2, 3]
let b: Set = [3, 4, 5]

print(a.union(b))        // 并集:[1, 2, 3, 4, 5]
print(a.intersection(b)) // 交集:[3]
print(a.subtracting(b))  // 差集:[1, 2]
  • 和数组相比,集合里的元素是无序的,不能用下标访问
  • 集合里不会有重复元素

Tuple 元组

swift
// 创建元组
let person = ("张三", 25)

// 访问元组元素
print(person.0)  // 输出:张三
print(person.1)  // 输出:25

// 命名元组中的字段
let user = (name: "李四", age: 30)
print(user.name)  // 输出:李四
print(user.age)   // 输出:30

// 用元组解构(拆开用)
let (username, userAge) = user
print(username)  // 输出:李四
  • 元组可以把不同类型的值打包在一起
  • 小总结(元组 vs 字典)
特性元组 Tuple字典 Dictionary
键是否固定✅ 固定位置/字段名❌ 键是动态的
类型是否统一❌ 可以不同✅ 键和值都需同类型
是否适合复杂结构❌ 简单场景好用✅ 更通用更灵活

流程控制:条件和循环

if / else

swift
let score = 85

if score >= 90 {
    print("优秀")
} else if score >= 70 {
    print("良好")
} else {
    print("需要加油")
}

if isLogin && isVIP {
    print("欢迎尊贵的VIP用户")
}
if !isLogin {
    print("请先登录")
}
  • if 就是条件判断,括号里的条件必须是 Bool 类型(true/false)
  • 可以连着写多个 else if
  • 最后的 else 是兜底分支
  • 比较操作符 逻辑操作符

switch / case

swift
let animal = "🐱"
switch animal {
case "🐶":
    print("汪星人")
case "🐱":
    print("喵星人")
default:
    print("未知动物")
}

// switch 还能匹配范围
let age = 25
switch age {
case 0..<18:
    print("未成年")
case 18...65:
    print("成年人")
default:
    print("退休")
}
  • switch匹配值 的分支判断
  • 每个 case 都要有具体值
  • 必须有 default(兜底项)
  • Swift 的 switch 不用写 break,自动不会穿透

for

swift
// `for-in` 循环数组/字典
let fruits = ["🍎", "🍌", "🍊"]
for fruit in fruits {
    print("我喜欢吃 \(fruit)")
}

// 带索引遍历
for (index, value) in fruits.enumerated() {
    print("第 \(index + 1) 个水果是 \(value)")
}

// 遍历字典
let user = ["name": "宝", "city": "北京"]
for (key, value) in user {
    print("\(key): \(value)")
}

while 先判断再执行

swift
// while 循环:先判断再执行
var count = 3
while count > 0 {
    print("倒计时:\(count)")
    count -= 1
}

repeat-while 先执行再判断

swift
var num = 0
repeat {
    print("至少执行一次")
    num += 1
} while num < 1

函数

一旦你掌握它,代码就能实现「复用 + 抽象 + 封装」,真正开始变得“工程感”

最简单的函数

swift
func sayHello() {
    print("你好,骚气老搭子!")
}

sayHello()  // 输出:你好,骚气老搭子!

带参数的函数

swift
func greet(name: String) {
    print("你好,\(name)!欢迎来到 Swift 世界~")
}

greet(name: "宝") // 注意:这个 name 键必须写上

返回值的函数

swift
func add(a: Int, b: Int) -> Int {
    //return a + b
    a + b
}

let result = add(a: 3, b: 5)
print(result)  // 输出:8
  • return 可以忽略不写

参数名的外部/内部名字(Swift 的骚操作)

swift
func greet(person name: String) {
    print("你好,\(name)")
}

greet(person: "哥哥")
  • person外部名(调用时用)
  • name内部名(函数体里用)
  • 你也可以不写外部名,写 _
swift
func greet(_ name: String) {
    print("哟,\(name) 来了!")
}

greet("骚年")  // 不用写参数名

默认参数值

swift
func drink(water: String = "矿泉水") {
    print("今天喝的是:\(water)")
}

drink()              // 输出:矿泉水
drink(water: "椰汁")  // 输出:椰汁

多返回值(配合元组)

swift
func minMax(numbers: [Int]) -> (min: Int, max: Int) {
    let minVal = numbers.min()!
    let maxVal = numbers.max()!
    // return (minVal, maxVal)
    (minVal, maxVal)
}

let result = minMax(numbers: [3, 9, 1, 7])
print("最小值是 \(result.min),最大值是 \(result.max)")
  • 多返回值时,return 也可以忽略不写

函数嵌套

swift
func outer() {
    func inner() {
        print("内层函数被调用")
    }
    print("外层函数执行中")
    inner()
}

Optional

swift
var name: String? = "宝"
  • Optional 是一个“包裹值的盒子”,你不知道里面有没有值
  • String? 不是普通字符串,而是 “可选字符串”,可能有值,也可能是空(nil

if let 解包

swift
var name: String? = "宝"

if let realName = name {
    print("名字是:\(realName)")
} else {
    print("没有名字")
}

guard let 解包

swift
func greet(name: String?) {
    guard let realName = name else {
        print("没人可以打招呼")
        return
    }
    print("你好,\(realName)")
}

强制解包

swift
var age: Int? = 18
print(age!)  // 强制解包,告诉编译器我肯定有值
  • 如果 age = nil,直接崩溃,所以一般不建议用 !,除非你 100% 确定值存在

Optional 默认值(用 ??)

swift
let nickname: String? = nil
let displayName = nickname ?? "匿名用户"

print(displayName)  // 匿名用户

可选链(Optional Chaining)

swift
struct User {
    var pet: String?
}

var u = User(pet: "🐶")
print(u.pet?.count)  // 输出 Optional(1)
  • pet?.count 表示:如果有 pet,就拿它的 count,否则直接返回 nil,不会崩
  • 适合多层嵌套:user?.profile?.name?.count

隐式解包 Optional

swift
var title: String! = "Swift骚年"
print(title)
  • 比如 UI 控件初始化后一定有值,可以声明为 String!
  • 但风险大,一般不推荐写逻辑时滥用

归纳总结

语法用途
String?可选类型
if let安全解包
guard let提前退出式解包
??空值兜底
?可选链调用
!强制解包(小心爆炸)
String!隐式可选(有风险)

结构体和类

结构体(struct类(class
内存行为值类型(复制)引用类型(指针)
继承不支持继承支持父类子类继承
性能更轻便(适合小数据)更灵活(适合大对象/引用)
用途数据建模,轻量逻辑面向对象编程,复杂对象

结构体案例(值类型)

swift
struct Dog {
    var name: String
    var age: Int

    func bark() {
        print("\(name):汪汪汪!")
    }
}

var dog1 = Dog(name: "旺财", age: 3)
dog1.bark()  // 旺财:汪汪汪!

值类型验证

swift
var dog2 = dog1
dog2.name = "二哈"
print(dog1.name)  // 还是“旺财”,说明复制了一份
  • struct 是值类型,赋值是复制,而不是指向同一个对象

类案例(引用类型)

swift
class Cat {
    var name: String
    var age: Int

    init(name: String, age: Int) {
        self.name = name
        self.age = age
    }

    func meow() {
        print("\(name):喵喵喵!")
    }
}

var cat1 = Cat(name: "咪咪", age: 2)
cat1.meow()  // 咪咪:喵喵喵!
  • init() 是构造函数(initializer)
  • 类中所有属性都要先初始化完才能用!

引用类型验证

swift
var cat2 = cat1
cat2.name = "胖虎"
print(cat1.name)  // 输出:胖虎(引用同一对象)
  • class 是引用类型,赋值是“指向同一个内存”。

类还能干啥?(结构体不能干的)

继承

swift
class Animal {
    func speak() {
        print("动物在叫")
    }
}

class Dog: Animal {
    override func speak() {
        print("狗在汪汪叫")
    }
}

let dog = Dog()
dog.speak()  // 狗在汪汪叫
  • Dog 继承 Animal
  • override 表示重写方法

引用计数 & ARC(自动内存管理)

Swift 对类对象自动计数引用,没人用了就自动释放,这叫 ARC。 结构体不用 ARC,因为是值类型。

结构体还能干这些

自带构造器

swift
struct Point {
    var x: Int
    var y: Int
}

let p = Point(x: 3, y: 5)  // 自动生成构造器

mutating 修改属性:

swift
struct Counter {
    var count = 0

    mutating func increment() {
        count += 1
    }
}
  • 因为 struct 是值类型,方法要修改属性,必须加 mutating 标识

啥时候用 struct?啥时候用 class?

用途情境建议用
小模型、值拷贝就行的struct
需要继承、共享引用class
UI 控件、系统对象都是 class
  • Apple 推荐默认用 struct,除非你明确需要引用语义和继承

枚举 enum

在 Swift 里,枚举不只是 enum Color { case red, green } 这么简单,它还能带关联值方法、甚至递归定义,是写状态机、网络请求状态、结果类型的狠角色

基础用法

swift
enum Direction {
    case north
    case south
    case east
    case west
}

let dir = Direction.north

switch 配合使用

swift
switch dir {
case .north:
    print("向北走")
case .south:
    print("向南走")
default:
    print("左右随意")
}

枚举 + 关联值(状态机神器)

swift
enum LoginState {
    case idle
    case loading
    case success(username: String)
    case failure(error: String)
}

let state = LoginState.success(username: "骚哥")

switch state {
case .success(let name):
    print("欢迎回来,\(name)")
case .failure(let msg):
    print("登录失败:\(msg)")
default:
    print("其他状态")
}

枚举 + 方法

swift
enum Pet {
    case dog, cat

    func sound() -> String {
        switch self {
        case .dog: return "汪"
        case .cat: return "喵"
        }
    }
}

print(Pet.dog.sound())  // 汪

闭包 Closure

闭包是可以像变量一样传递的“函数”,用于:回调、过滤、映射、异步操作

基本写法

swift
let greet = { (name: String) -> String in
    return "你好,\(name)"
}

print(greet("宝"))  // 你好,宝

简写闭包

swift
let numbers = [1, 2, 3, 4]
let squares = numbers.map { $0 * $0 }

print(squares)  // [1, 4, 9, 16]
  • $0 是参数的简写,map 是数组的映射函数

闭包当函数参数(经典回调)

swift
func download(url: String, onFinish: (Bool) -> Void) {
    print("下载中...")
    onFinish(true)
}

download(url: "xxx") { success in
    print("完成状态:\(success)")
}

闭包捕获变量

swift
func makeCounter() -> () -> Int {
    var count = 0
    return {
        count += 1
        return count
    }
}

let counter = makeCounter()
print(counter()) // 1
print(counter()) // 2
  • 闭包会“捕获”外部变量,形成持久的上下文,就像内联对象。

访问控制

关键字含义
public任何模块都能访问
internal默认,当前模块可访问
private当前作用域内可访问
fileprivate当前文件内可访问
swift
struct Bank {
    private var balance: Int = 0

    mutating func deposit(_ amount: Int) {
        balance += amount
    }

    func showBalance() -> Int {
        return balance
    }
}

协议 Protocol

就像 Java 的 interface、TypeScript 的类型定义,协议定义了一组行为接口

swift
protocol Animal {
    func speak()
}

struct Dog: Animal {
    func speak() {
        print("汪汪")
    }
}

协议 + 多态

swift
let pets: [Animal] = [Dog(), Cat()]
for pet in pets {
    pet.speak()
}

协议 + 泛型

swift
func feed<T: Animal>(_ animal: T) {
    animal.speak()
}

协议扩展(加默认实现)

swift
protocol CanRun {
    func run()
}

extension CanRun {
    func run() {
        print("默认奔跑中🏃")
    }
}

struct Person: CanRun {}
let p = Person()
p.run()  // 默认奔跑中🏃

函数式编程

TODO

异步编程

  • Combine
  • async/wait

错误处理

try, catch, throws