Swift 基础语法
Foundation

Swift 基础语法

基本理解

Swift 相比 OC 有哪些优点

  • Swift 是类型安全的语言,注重安全,OC注重灵活
  • Swift 注重面向协议编程、函数式编程、面向对象编程,OC注重面向对象编程
  • Swift 注重值类型,OC 注重指针和引用
  • Swift 是静态类型语言,OC 是动态类型语言
  • Swift 容易阅读,文件结构和大部分语法简易化,只有 .swift 文件,结尾不需要分号
  • Swift 中的可选类型,是用于所有数据类型,而不仅仅局限于类。相比于 OC 中的 nil 更加安全和简明
  • Swift 中的泛型类型更加方便和通用,而非 OC 中只能为集合类型添加泛型
  • Swift 中各种方便快捷的[高阶函数](函数式编程)(Swift的标准数组支持三个高阶函数:map, filterreduce 以及 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 = nil

2. 解包方式

  • 强制解包(不推荐):使用 !
  • 安全解包(推荐):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. 区别

特性structclass
类型值类型引用类型
继承
析构函数
可变性需 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() {}
}