Swift 基础语法
基本理解
Swift 相比 OC 有哪些优点
- Swift 是类型安全的语言,注重安全,OC注重灵活
- Swift 注重面向协议编程、函数式编程、面向对象编程,OC注重面向对象编程
- Swift 注重值类型,OC 注重指针和引用
- Swift 是静态类型语言,OC 是动态类型语言
- Swift 容易阅读,文件结构和大部分语法简易化,只有
.swift文件,结尾不需要分号 - Swift 中的可选类型,是用于所有数据类型,而不仅仅局限于类。相比于 OC 中的
nil更加安全和简明 - Swift 中的泛型类型更加方便和通用,而非 OC 中只能为集合类型添加泛型
- Swift 中各种方便快捷的[高阶函数](函数式编程)(Swift的标准数组支持三个高阶函数:
map,filter和reduce以及map的扩展flatMap) - Swift 新增了两种权限,细化权限。
open>public>internal(默认) >fileprivate>private - Swift 中独有的元组类型(tuples),把多个值组合成复合值。元组内的值可以是任何类型,并不要求是相同类型的。
- Swift 支持函数式编程,ObjC 本身是不支持的,需要通过引入 ReactiveCocoa 这个库才可支持函数式编程。
变量与常量
1. var 与 let 的区别
- var 声明变量,值可修改。
- let 声明常量,值不可修改。
var name = "Alice"
name = "Bob" // ✅ 可修改
let age = 25
age = 30 // ❌ 报错2. Swift 是强类型语言吗?
是。变量类型一旦确定,不能再赋不同类型的值。
var number = 10 // Int
number = "Hello" // ❌ 类型不匹配可选值(Optionals)
1. 可选值的作用
表示变量可能有值,也可能为 nil。
var name: String? = "Alice"
name = nil2. 解包方式
- 强制解包(不推荐):使用 !
- 安全解包(推荐):if let 或 guard let
if let unwrapped = name {
print(unwrapped)
}3. 隐式解包
在声明时使用 String!,可直接使用。
var text: String! = "Hello"
print(text.count)控制流
1. 常见控制语句
if、switch、for-in、while、repeat-while、guard
2. switch 特点
- 不需要 break。
- 必须覆盖所有情况。
- 支持模式匹配。
let score = 85
switch score {
case 90...100: print("优秀")
case 60..<90: print("及格")
default: print("不及格")
}函数(Functions)
1. 基本定义
func greet(name: String) -> String {
return "Hello, \(name)"
}2. 参数命名
func greet(to person: String, from sender: String) {
print("Hi \(person), from \(sender)")
}
greet(to: "Alice", from: "Bob")3. 默认参数与可变参数
func sayHello(_ name: String = "World") { print("Hello, \(name)") }
func sum(_ numbers: Int...) -> Int { numbers.reduce(0, +) }闭包(Closures)
1. 闭包定义
匿名函数,可捕获上下文。
let add = { (a: Int, b: Int) -> Int in return a + b }2. 闭包简写
let doubled = [1, 2, 3, 4].map { $0 * 2 }结构体与类
1. 区别
| 特性 | struct | class |
|---|---|---|
| 类型 | 值类型 | 引用类型 |
| 继承 | ❌ | ✅ |
| 析构函数 | ❌ | ✅ |
| 可变性 | 需 mutating | 不需修饰 |
2. 值类型与引用类型
struct 赋值时复制,class 赋值时共享同一对象。
枚举(Enum)
1. 关联值
enum Result {
case success(data: String)
case failure(error: String)
}2. 原始值
enum Direction: String {
case north = "N", south = "S"
}属性与方法
1. 计算属性
struct Rectangle {
var width, height: Double
var area: Double { width * height }
}2. 属性观察器
var count = 0 {
willSet { print("即将修改为 \(newValue)") }
didSet { print("已修改为 \(count)") }
}协议与扩展
1. 协议定义
protocol Runnable {
func run()
}
class Person: Runnable {
func run() {
print("Running...")
}
}2. 扩展
extension Int {
var squared: Int { self * self }
}
print(5.squared)泛型(Generics)
1. 泛型函数
func swapTwo<T>(_ a: inout T, _ b: inout T) {
let temp = a; a = b; b = temp
}2. 泛型约束
func findIndex<T: Equatable>(of value: T, in array: [T]) -> Int? {
for (i, item) in array.enumerated() where item == value { return i }
return nil
}内存管理(ARC)
1. ARC 原理
对象引用计数为 0 时自动释放。
2. 循环引用与解决
使用 weak 或 unowned。
class Person { var pet: Pet? }
class Pet { weak var owner: Person? }并发(Concurrency)
1. async / await
func fetchImage() async -> UIImage? {
try? await Task.sleep(nanoseconds: 1_000_000_000)
return UIImage(named: "example")
}2. actor 并发安全
actor Counter {
var value = 0
func increment() { value += 1 }
}错误处理(Error Handling)
1. 基本语法
enum NetworkError: Error { case notFound, unauthorized }
func fetchData() throws { throw NetworkError.notFound }
do {
try fetchData()
} catch {
print("发生错误:\(error)")
}2. try? 与 try!
- try? 出错返回 nil
- try! 出错崩溃
访问控制(Access Control)
| 关键字 | 可见范围 |
|---|---|
| open | 模块外可继承、可重写 |
| public | 模块外可访问 |
| internal | 模块内(默认) |
| fileprivate | 当前文件 |
| private | 当前作用域 |
常见高阶函数
1. map:映射转换
对集合中每个元素进行转换,返回新数组。
let numbers = [1, 2, 3, 4]
let doubled = numbers.map { $0 * 2 }
// [2, 4, 6, 8]常见考点:
- 不会修改原数组。
- 闭包中返回的类型可与原类型不同。
2. filter:条件筛选
过滤出满足条件的元素。
let evens = numbers.filter { $0 % 2 == 0 }
// [2, 4]常见考点:
- 返回新数组。
- 闭包返回 Bool。
3. reduce:聚合计算
将集合元素通过初始值和运算符累积。
let sum = numbers.reduce(0, +)
// 10自定义示例:
let result = numbers.reduce("结果:") { $0 + " \($1)" }
// "结果: 1 2 3 4"常见考点:
- 初始值类型决定返回值类型。
- 常用于求和、拼接、统计。
4. compactMap:过滤 nil 并解包
let values = ["1", "a", "3"]
let validNumbers = values.compactMap { Int($0) }
// [1, 3]常见考点:
- 先 map 再移除 nil。
- 常用于类型转换、数据清洗。
5. flatMap:展平多维数组
let nested = [[1, 2], [3, 4], [5]]
let flattened = nested.flatMap { $0 }
// [1, 2, 3, 4, 5]常见考点:
- 适用于二维数组扁平化。
- 与 map 不同,返回值自动合并层级。
6. 综合题示例
题目:计算字符串数组中所有数字的总和
let arr = ["1", "a", "5", "3"]
let total = arr.compactMap { Int($0) }.reduce(0, +)
print(total) // 输出 9题目:过滤偶数并平方
let result = numbers.filter { $0 % 2 == 0 }.map { $0 * $0 }
// [4, 16]小结
Swift 的常用高阶函数核心要点:
- map:转换
- filter:筛选
- reduce:聚合
- compactMap:解包过滤
- flatMap:扁平化
掌握这五个函数,能应对大多数集合处理和函数式编程类面试题。
综合题与高频问答
1. 闭包循环引用
原因:闭包捕获 self。
解决:[weak self] 或 [unowned self]。
2. struct 无循环引用原因
值类型传递,复制拷贝,无共享引用。
3. async/await 相对 GCD 优势
语法简洁,可读性高,结构化管理并发。
4. 单例模式
class Singleton {
static let shared = Singleton()
private init() {}
}