Swift 的类型系统一向被认为「安全又严格」,但很多初学者会被搞混:为什么
var a: Int = nil会报错?struct和class有什么本质区别?什么是「值类型」与「引用类型」?本篇文章帮你一次性捋清楚这些概念!
🟢 普通类型 vs 可选类型
在 Swift 中,类型首先可以分为两大类:
✅ 普通类型
- 必须有值,不能是 nil。
- 比如:
Int,Double,String, 自定义结构体、枚举、类对象(如果没有加?)。
var score: Int = 100
score = 200 // OK
score = nil // ❌ 报错
✅ 可选类型(Optional)
- 可以有值,也可以没有值(即 nil) 。
- 写法:在类型后加
?,例如Int?,String?,[Int]?。
var score: Int? = nil
score = 300 // OK
score = nil // 也 OK
本质上,可选类型就是一个「包装器」,相当于下面的枚举:
enum Optional<Wrapped> {
case some(Wrapped)
case none
}
🟠 普通类型的进一步分类:值类型 & 引用类型
当我们说「普通类型」时,还要进一步区分它是 值类型(Value Type) 还是 引用类型(Reference Type) 。
✅ 值类型(Value Type)
- 赋值或传参时会复制一份新的独立副本,互不影响。
- 代表:
struct,enum,Tuple,Array,Dictionary,Set。
var a = 10
var b = a // 复制
b = 20
print(a) // 10
再比如自定义结构体:
struct Point {
var x: Int
var y: Int
}
var p1 = Point(x: 0, y: 0)
var p2 = p1
p2.x = 100
print(p1.x) // 0
✅ 引用类型(Reference Type)
- 赋值或传参时,指向同一个内存地址,互相影响。
- 代表:
class、Closure(闭包)。
class Person {
var name: String
init(name: String) { self.name = name }
}
var p1 = Person(name: "Alice")
var p2 = p1
p2.name = "Bob"
print(p1.name) // Bob
🔵 可选类型其实是「包装」
很多人会问:「可选类型到底是值类型还是引用类型?」
答案是:可选类型其实是「包装器」,它本身是值类型(一个枚举),但它内部可以包裹值类型或引用类型。
比如:
var num: Int? = 10 // 包裹一个值类型 Int
var obj: Person? = Person(name: "Tom") // 包裹一个引用类型 Person
⚖️ 一张图总结 Swift 类型体系
┌─────────────┐
│ Swift 类型 │
└──────┬──────┘
│
┌──────────────┴──────────────┐
│ │
┌─────────────┐ ┌─────────────┐
│ 普通类型 │ │ 可选类型 │
└──────┬──────┘ └──────┬──────┘
│ │
┌────┴────┐ 包裹任何普通类型
│ │
值类型 引用类型
✅ Swift 类型 = 普通类型(再分值/引用) + 可选类型(包装)
✅ 值类型默认复制副本,安全、独立;引用类型共享内存,更灵活但也容易出错
✅ 可选类型让「有值 / 无值」更安全、更显式
想要
nil?请用「可选」;想要独立?请用「值类型」;想要共享?请用「引用类型」。