Appearance
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) // 输出:8return可以忽略不写
参数名的外部/内部名字(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继承Animaloverride表示重写方法
引用计数 & 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.northswitch 配合使用
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