Chr*_*res 11 reference-counting value-type reference-type automatic-ref-counting swift
当引用类型的属性具有相互较强的所有权(或具有闭包)时,会发生Swift中的引用循环.
但是,是否有可能只使用值类型的参考周期?
我在游乐场尝试了这个没有成功(错误:不允许递归值类型'A').
struct A {
var otherA: A? = nil
init() {
otherA = A()
}
}
Run Code Online (Sandbox Code Playgroud)
正如编译器告诉你的那样,你要做的是非法的.正是因为这是一种价值类型,没有连贯,有效的方式来实现你所描述的内容.如果类型需要引用自身(例如,它具有与自身类型相同的属性),则使用类,而不是结构.
或者,您可以使用枚举,但只能以特殊的,有限的方式使用:枚举大小写的关联值可以是该枚举的实例,前提是大小写(或整个枚举)indirect:
enum Node {
case None(Int)
indirect case left(Int, Node)
indirect case right(Int, Node)
indirect case both(Int, Node, Node)
}
Run Code Online (Sandbox Code Playgroud)
免责声明:我在这里对 Swift 编译器的内部工作进行了(希望受过教育的)猜测,因此请谨慎使用。
除了值语义,问问自己:为什么我们有结构?优势是什么?
一个优点是我们可以(阅读:想要)将它们存储在堆栈上(分别在对象框架中),即就像其他语言中的原始值一样。特别是,我们不想在堆上分配专用空间来指向。这使得访问结构值更有效:我们(阅读:编译器)总是知道它在内存中找到值的确切位置,相对于当前帧或对象指针。
为了让编译器解决这个问题,在确定堆栈或对象帧的结构时,它需要知道为给定的结构值保留多少空间。只要结构值是固定大小的树(不考虑对对象的传出引用;它们指向堆对我们来说不感兴趣),那很好:编译器可以将它找到的所有大小相加。
如果您有递归结构,这将失败:您可以通过这种方式实现列表或二叉树。编译器无法静态地弄清楚如何将这些值存储在内存中,因此我们必须禁止它们。
注意:同样的推理解释了为什么结构是按值传递的:我们需要它们在物理上处于新的上下文中。
| 归档时间: |
|
| 查看次数: |
3989 次 |
| 最近记录: |