当前位置: 首页 > 面试题库 >

为什么要选择结构而非类?

宇文俊明
2023-03-14
问题内容

在Java背景下玩Swift,为什么要选择Struct而不是Class?似乎它们是同一回事,但Struct提供的功能较少。为什么选择它呢?


问题答案:

根据非常流行的WWDC 2015演讲《
Swift中的面向协议的编程》(视频,成绩单),Swift提供了许多功能,这些功能在许多情况下都比类更好。

如果结构相对较小且可复制,则结构是可取的,因为与在类中多次引用相同实例相比,复制要安全得多。当将变量传递给许多类和/或在多线程环境中时,这一点尤其重要。如果您始终可以将变量的副本发送到其他位置,则不必担心其他位置会更改您下面的变量的值。

使用Structs,无需担心内存泄漏或多个线程争夺访问/修改变量的单个实例的麻烦。(从更专业的角度来说,例外是在闭包内部捕获结构时,因为它实际上是在捕获对实例的引用,除非您明确地将其标记为要复制)。

类也可能变得肿,因为类只能从单个超类继承。这鼓励我们创建巨大的超类,其中包含松散相关的许多不同能力。使用协议,尤其是协议扩展,可以在其中提供协议的实现,可以消除类对实现此类行为的需要。

演讲列出了首选班级的这些情况:

  • 复制或比较实例没有意义(例如Window)
  • 实例的生存期与外部影响(例如TemporaryFile)有关
  • 实例只是“接收器”-到外部状态(例如CGContext)的只写管道

这意味着结构应该是默认值,而类应该是后备值。

另一方面,Swift编程语言文档有些矛盾:

结构实例始终按值传递,而类实例始终按引用传递。这意味着它们适合于各种任务。在考虑项目所需的数据结构和功能时,请确定是将每个数据结构定义为类还是结构。

作为一般准则,请考虑在以下一个或多个条件适用时创建结构:

  • 该结构的主要目的是封装一些相对简单的数据值。
  • 合理地预期,当您分配或传递该结构的实例时,将复制而不是引用封装的值。
  • 结构存储的任何属性本身都是值类型,也应该期望将其复制而不是引用。
  • 该结构不需要从另一个现有类型继承属性或行为。

良好的结构候选人包括:

  • 尺寸均为Double的几何形状的大小,可能封装了width属性和height属性。
  • 一种引用系列中范围的方法,可能封装了Int类型的start属性和length属性。
  • 3D坐标系中的一个点,可能封装了x,y和z属性,每个属性均为Double类型。

在所有其他情况下,请定义一个类,然后创建该类的实例以通过引用进行管理和传递。实际上,这意味着大多数自定义数据构造应该是类,而不是结构。

在这里,我们声称我们应该默认仅在特定情况下使用类和结构。最终,您需要了解值类型与引用类型的真实含义,然后可以就何时使用结构或类做出明智的决定。另外,请记住,这些概念一直在发展,并且在进行面向协议的编程演讲之前编写了Swift编程html" target="_blank">语言文档。



 类似资料:
  • 在使用来自Java背景的Swift时,为什么要选择结构而不是类呢?似乎它们是一样的,结构提供的功能较少。那为什么选择它呢?

  • 作为 RIA 工程师,在日常工作中调试各种页面内 BUG 已经是家常便饭,随着 AJAX 技术的盛行,现在出现了众多值得称道调试的工具: 分析 DOM 结构、CSS 及 Javascript 调试:FireBug(Firefox),IE WebDeveloper(IE)、Microsoft Script Editor 等 网络抓包工具:HttpWacth(强力推荐,V6.0+ 已经同时支持 IE

  • 2.3.1 块IF构造 a) 块IF的组成和执行 块IF的一般形式可写成: IF(逻辑表达式) THEN ← 块IF语句 块1 ← then块 ELSE 块2 ← else块 END IF 块IF语句不是一个单独语句。块IF语句、ELSE语句和ENDIF语句只能用在块IF中而不能单独使用,它们必须和块IF中其它语句联系起来共同起作用。可以说一个块IF是一个语句块(决不能只包括一个语句),用来实现选

  • 目前正在使用React Native,并尝试使用React Native nfc ios和React national nfc,以便我可以在ios和Android之间进行跨设备通信。我发现他们无法沟通,但我认为这是由于一个更广泛的问题(因为其他现有的应用程序也无法工作)。 如果我在iPhone7上下载NFC阅读器应用程序,在Android上下载NFC写入器应用程序,它们就无法通信。这是为什么呢?

  • 如果你曾经使用过构建工具,你可能会对遇到的问题感到很沮丧,构建工具不是应该自动帮你完成项目的构建吗?你不得不向性能、扩展性等妥协。 比如你在构建一个项目的发布版本时,你要把一个文件拷贝到指定的位置,你在项目的元数据那里添加了版本的描述,如果版本号匹配一个特定的数字时,就把文件从A拷贝到B处。如果你依赖XML来构建,你要实现这个任务就像噩梦一样,你只能通过非标准的机制来添加一些脚本到构建中,结果就是

  • 来源:https://github.com/atom-china/manual 这个世界上有那么多种编辑器,为什么你要花时间学习和使用 Atom 呢? 虽然 Sublime 和 TextMate 之类的编辑器已经非常好用了,但它们仅提供了很有限的拓展性。而在另一个极端,Emacs 和 Vim 提供了灵活的拓展性,但它们并不是很友好,需要使用专用的编程语言来配置和拓展。 我们觉得我们可以做得更好。我