为什么Swift类和结构的设置方式如何呢?

时间:2017-11-22 04:45:08

标签: swift class inheritance struct initialization

在Swift中,类具有继承性和结构性。同时,类实例存在于堆中,而结构实例存在于堆栈中。

这意味着只允许四种可能中的两种:你可以拥有支持继承的东西,它们存在于堆中,或者你可以拥有不支持继承并且存在于堆栈中的东西。你不能拥有支持继承并且存在于堆栈中的东西,并且你不能拥有不支持继承并且存在于堆中的东西。

这是为什么?是什么让后两种可能性变得不可取?

对于一个安可,为什么结构会获得一个免费的初始化程序,但课程不是?

1 个答案:

答案 0 :(得分:2)

这是关于值类型引用类型的合理设计。

Class作为引用类型,其继承对应于身份。虽然Struct作为值类型没有标识,除了它们包含的字段顶部的值,因此可以自由复制。如果您尝试将子字段添加到“继承结构”,则更改该结构的字段或值,并且它们之间不再存在“is-a”关系,如Class继承,因为说具有较少字段的值类型“is-a”另一个 value-type 是没有意义的。

“继承结构”添加的子字段在复制时可能会被任意丢失(例如,C ++调用时会调用复制构造函数),并使 compatibility 等特性失去意义。另一方面,Class没有这些问题,因为Class的每个实例都具有唯一的标识,并且只传递对该实例的引用。

让我们在2D平面上取一个点,这是一个Struct,包含两个字段:xy。说有另一个子结构代表3D世界的一个点,它有一个子场z

当我们喜欢的时候:

point2D = point3D;

然后在作业线上会发生什么?因为point2D占用的内存已经修复了吗?

从您的问题来看,它直接与堆和堆栈本身的特性相关,当程序进入函数或分配局部变量时,它们被推送到当前堆栈帧(具有固定大小),并且在退出函数后,将进行poped / deallocated,这使得为CPU进行优化变得相对容易。

另一方面,堆具有额外的复杂性,因为程序员能够使用mallocfree之类的命令直接与其进行交互 - 从而导致额外的请求和释放时间 - 这会产生更多成本时间它们在初始化时可能需要额外的内存 - 对于开头可能包含或不包含值的字段 - 这会占用更多的空间成本等。将这些特性混淆会使优化变得更加复杂。