拥有 Java 背景,玩过 Swift,为什么要选择 Struct 而不是 Class?看起来它们是同一件事,只是结构提供的功能较少。那为什么选择它呢?
根据非常流行的 WWDC 2015 演讲Swift 中的面向协议编程 (video https://developer.apple.com/videos/wwdc/2015/?id=408, 成绩单 http://asciiwwdc.com/2015/sessions/408?q=protocol),Swift 提供了许多功能,使结构在许多情况下比类更好。
如果结构相对较小且可复制,那么结构会更可取,因为复制比类中对同一实例的多个引用更安全。当将变量传递给许多类和/或多线程环境中时,这一点尤其重要。如果您始终可以将变量的副本发送到其他地方,那么您永远不必担心其他地方会更改您下面的变量的值。
使用结构,无需担心内存泄漏或多个线程竞相访问/修改变量的单个实例。 (对于更具技术头脑的人来说,例外情况是在闭包内捕获结构体时,因为这样它实际上捕获了对实例的引用,除非您显式地将其标记为要复制)。
类也可能变得臃肿,因为类只能从单个超类继承。这鼓励我们创建巨大的超类,其中包含许多松散相关的不同能力。使用协议,特别是使用可以提供协议实现的协议扩展,可以消除对类来实现此类行为的需要。
演讲列出了首选课程的这些场景:
- 复制或比较实例没有意义(例如,
Window
)
- 实例生命周期与外部影响相关(例如,
TemporaryFile
)
- 实例只是“接收器”——通向外部状态的只写管道(例如,
CGContext
)
这意味着结构应该是默认的,而类应该是后备的。
另一方面,Swift 编程语言 https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/ClassesAndStructures.html#//apple_ref/doc/uid/TP40014097-CH13-XID_108文档有些矛盾:
结构实例总是按值传递,而类
实例始终通过引用传递。这意味着他们是
适合不同类型的任务。当你考虑数据时
项目所需的结构和功能,决定
每个数据结构是否应该被定义为一个类或者一个
结构。
作为一般准则,当一个或多个
以下条件适用:
- 该结构的主要目的是封装一些相对简单的数据值。
- 当您分配或传递一个值时,可以合理地预期封装的值将被复制而不是被引用。
该结构的实例。
- 该结构存储的任何属性本身都是值类型,也期望它们被复制而不是引用。
- 该结构不需要从另一个现有类型继承属性或行为。
结构的良好候选示例包括:
- 几何形状的大小,可能封装宽度属性和高度属性,两者都是 Double 类型。
- 一种引用系列中的范围的方法,可能封装一个起始属性和一个长度属性,两者都是 Int 类型。
- 3D 坐标系中的一个点,可能封装 x、y 和 z 属性,每个属性都是 Double 类型。
在所有其他情况下,定义一个类并创建该类的实例
通过引用进行管理和传递。在实践中,这意味着
大多数自定义数据构造应该是类,而不是结构。
这里它声称我们应该默认使用类并仅在特定情况下使用结构。最终,您需要了解值类型与引用类型的现实世界含义,然后您可以就何时使用结构或类做出明智的决定。另外,请记住,这些概念总是在不断发展,并且 Swift 编程语言文档是在面向协议编程演讲之前编写的。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)