nil 在可选类型中,它背后到底是什么?它在记忆中是什么样子的?
nil in an optional type, what exactly is behind it? what it looks like in the memory?
class Person{
let name: String
init(name: String) {
self.name = name
}
}
var john: Person?
上面的代码片段定义了一个名为 john
的可选类型的变量。此时变量初始值为nil.
一个class实例将其值保存在堆space中,并将引用存储在堆栈中。 (如果我错了请纠正我)john
在这种情况下是一个未分配的可选变量,它还没有引用任何实例。
问:PC 将名称字符串"john"存储在哪里?它是否已经创建并存储在 堆栈 中并等待引用 heap 中的某个实例?值 "nil" 存储在哪里?
非常感谢
在幕后,可选项实际上只是具有关联值的通用 enum
:
enum Optional<T> {
case some(T)
case none
}
nil
只是 shorthand 对于 Optional.none
。因此,在您的示例中,john
已经拥有它需要的所有存储空间;它被设置为一个值,该值恰好 代表 虚无。现在,由于 Person
是一个 class,它是一个引用类型,"all the storage it needs" 实际上只是一个指针的空间。对于所有 class 个实例,实例属性的存储将在初始化时创建。
结论: 最初有一个 enum
的内存和一个指向 Person
的关联指针。然后,在初始化变量之后,当然还有一个 Person
实例。
有了这个
var john: Person?
在 Stack
之上添加了一个内存插槽。
这个插槽的类型是 Optional
类型的值 Person
Optional<Person>
我们在这个内存位置找到了 Optional.none
值。
之后
john = Person(name: "Mr Robot")
一些内存被分配到Heap
。
然后按照Person initializer
的逻辑写入此内存。
然后让我们回到堆栈。
这里 Optional.none
被替换为值 Optional.some
并且 Person
对象的地址内存被写入枚举值的一个特殊字段中。
class Person{
let name: String
init(name: String) {
self.name = name
}
}
var john: Person?
上面的代码片段定义了一个名为 john
的可选类型的变量。此时变量初始值为nil.
一个class实例将其值保存在堆space中,并将引用存储在堆栈中。 (如果我错了请纠正我)john
在这种情况下是一个未分配的可选变量,它还没有引用任何实例。
问:PC 将名称字符串"john"存储在哪里?它是否已经创建并存储在 堆栈 中并等待引用 heap 中的某个实例?值 "nil" 存储在哪里?
非常感谢
在幕后,可选项实际上只是具有关联值的通用 enum
:
enum Optional<T> {
case some(T)
case none
}
nil
只是 shorthand 对于 Optional.none
。因此,在您的示例中,john
已经拥有它需要的所有存储空间;它被设置为一个值,该值恰好 代表 虚无。现在,由于 Person
是一个 class,它是一个引用类型,"all the storage it needs" 实际上只是一个指针的空间。对于所有 class 个实例,实例属性的存储将在初始化时创建。
结论: 最初有一个 enum
的内存和一个指向 Person
的关联指针。然后,在初始化变量之后,当然还有一个 Person
实例。
有了这个
var john: Person?
在 Stack
之上添加了一个内存插槽。
这个插槽的类型是 Optional
类型的值 Person
Optional<Person>
我们在这个内存位置找到了 Optional.none
值。
之后
john = Person(name: "Mr Robot")
一些内存被分配到Heap
。
然后按照Person initializer
的逻辑写入此内存。
然后让我们回到堆栈。
这里 Optional.none
被替换为值 Optional.some
并且 Person
对象的地址内存被写入枚举值的一个特殊字段中。