当我必须在Swift中的类、结构和枚举之间进行选择时,我应该如何推理?

当我必须在Swift中的类、结构和枚举之间进行选择时,我应该如何推理?,swift,Swift,由于类、结构和枚举都有构造函数、属性和计算属性,在选择它们时应该如何推理?对于初学者,类是按引用传递的,结构是按副本传递的 枚举仍然是一种特殊类型,用于指定枚举。它们应该像以前一样使用 一般来说,类与结构的选择应该与以前没有太大区别。类仍然适用于较大/复杂的对象,而结构适用于较小、孤立的模型对象。结构有协议这一事实现在应该可以简化代码并提高效率。(类实例不接收默认的成员初始值设定项) 所有结构都有一个自动生成的成员初始值设定项, 您可以使用它初始化新结构的成员属性 实例。新实例的属性的初始值可以

由于类、结构和枚举都有构造函数、属性和计算属性,在选择它们时应该如何推理?

对于初学者,类是按引用传递的,结构是按副本传递的

枚举
仍然是一种特殊类型,用于指定枚举。它们应该像以前一样使用

一般来说,类与结构的选择应该与以前没有太大区别。类仍然适用于较大/复杂的对象,而结构适用于较小、孤立的模型对象。结构有协议这一事实现在应该可以简化代码并提高效率。

(类实例不接收默认的成员初始值设定项)

所有结构都有一个自动生成的成员初始值设定项, 您可以使用它初始化新结构的成员属性 实例。新实例的属性的初始值可以 按名称传递给成员初始值设定项:

这非常有意义,因为它们是值类型(因此是不可变的)


枚举也是值类型。类是引用类型。这里没有真正的惊喜。

克里斯托弗和杰克·吴的答案很好,但我觉得他们没有触及枚举,或者忽略了枚举的重要性。Swift枚举是(意味着)代数数据类型的完整实现。类和结构传统上用于在面向对象语言中为数据建模,但枚举通常仅限于作为一种方便的方式来使用,以将变量的值限制在有限的可能性范围内。例如(C++):

Swift枚举可以实现上述功能,但它们可以实现更多功能。当然,《语言指南》中有一个非常好的例子,但我所知道的最好的例子是Scott Wlaschin的介绍,它真正说明了用代数数据类型建模数据的意义:

您可能会从整个演示中受益,但要真正“理解”要点,您需要看到的是幻灯片60,其中他展示了如何在典型的业务线应用程序中模拟“支付方法”

演示文稿中的示例是F#中的,但F#离Swift并不远,您可以很容易地在它们之间进行映射。例如,Swift中的付款方式枚举如下所示:

enum PaymentMethod {
    case cash // No extra data needed.
    case cheque(Int) // Cheque #.
    case card(CardType, CardNumber) // 2 pieces of extra data.
}
上述要点是,每个订单的付款方式只能是上述三种方式中的一种。编译器将不允许任何其他操作。这是构建整个类层次结构以对这些几乎微不足道的事情建模的一个非常简洁的替代方法


演示从这里开始,最好的部分是Swift可以做F#在数据建模、使用可选类型等方面所能做的一切。

类和其他命名类型(结构/枚举)之间最重要的区别是:


结构不能是任何东西的子类(或者可以说是子结构)。它们本身也不能被细分。继承与结构完全不符。枚举也是如此。

我认为这是一个非常精细的讨论!我喜欢这里表达的想法:

有很多细节,还有他们的建议。我在这里复制了他们的总结,但这是一篇完整的文章

  • 枚举由有限个案例中的一个进行初始化,如下所示: 完全由其案例定义,并且应始终有效 实例化时的实例
  • structs应在以下情况下使用: 没有有限数量的有效实例(例如枚举实例)和 结构也不构成对象的完整定义,但 而是对象的属性
  • 类完全定义了主 对象模型中的参与者及其属性和交互

除了关于类、结构和枚举的实际用法的建议外,下面的比较澄清了它们之间的能力


一般来说,当定义的数据相对简单,不需要担心引用,或者不需要继承另一个数据结构的属性和方法时,可以使用结构而不是类

如果您有初始化后不应更改的数据,我们可以确保在编译时使用结构

在您知道对象的标识将非常重要的情况下使用类。换句话说,在希望多个代码区域指向同一对象实例的情况下使用类

在您知道对象的值很重要的情况下使用结构。换句话说,在两个不同的代码区域是否引用同一个实例来复制实例的情况下,结构非常适合

如果需要在程序的各个部分之间共享可变状态,则应使用类


如果您需要继承,或者您知道您想要传递对周围对象的引用,请使用类。

“类是按引用传递”否。Swift总是按值传递,参数没有标记为
inout
,就像Java总是按值传递一样。对象(类的实例)不是值,不能“传递”;相反,您只能通过指向对象的指针来操作对象。结构是值。当参数不是
inout
@newacct Great时,所有类型都按值传递!谢谢你的澄清。这并没有改变答案中的任何内容,正如你所说,对象总是通过复制指针来传递的,实际上总是“通过引用传递”的。在这里,我真的不想讨论语义,但我应该指出,苹果的措辞正是“类通过引用传递”。当然,参数/引用是按值传递的。我还想补充一点,类可以继承,结构不能继承。随便说说,有没有关于“有区别的联合”的例子
enum MaritalStatus { Unmarried, Married, Divorced, WidowedOrWidowered };
MaritalStatus m = Unmarried;
enum PaymentMethod {
    case cash // No extra data needed.
    case cheque(Int) // Cheque #.
    case card(CardType, CardNumber) // 2 pieces of extra data.
}