原文地址:https://www.raywenderlich.com/119881/enums-structs-and-classes-in-swift
回想只使用OC语言进行开发的时候,封装功能被限制在类中。然而,现在可以使用Swift进行开发,enums, structs和classes同样也具有了封装的功能。
这些类型和protocols结合,会创造出令人惊奇的功能。他们有许多共同的功能,也有不少重要的区别。
本教程的目的是:
- 介绍一些enums,structs和classes的使用经验。
- 当你使用它们的时候,能帮你解决一些问题。
- 介绍他们是如何工作的。
在读取本教程之前请确定你已经对Swift有了一些了解并具有一些面向对象的经验。
概览
Swift最大的卖点是:safety, speed, simplicity。
Safety意味着你很难因为"不小心","不按常规","记忆不清"儿写出难以发现的bug。Swift使你的开发工作更加安全,因为他会试图在编译阶段报告你的bug,而不是在运行时阶段挂掉你的app。
此外,Swift可以是你的代码更加干净明了并易于理解,优化器可以使应用运行的更快。
Swift语言核心简单且高度正规化,它仅仅建立在很少量的几个核心概念之上。尽管它的规则相对简单,但是功能却十分强大。
使其简单且功能强大的重要原因是Swift的类型系统type system

Swift的类型系统十分强大,尽管它只有6种类型。它不像一些其它语言一样字面上拥有十多种类型,而Swift只有6种。
四种组合类型:protocol, enum, struct, class. 两种复合类型:tuple, function.
还有一些基础类型:Bool, Int, Uint, Float, Double, Character, String ,Array, Set, Dictionary, Optional, 等。然而,这些类型都来自标准库。
本教程以model types为基础的组合类型enum, struct和class为重点。
开始
创建一个playground项目并命名为Shapes,选择平台为OS X.清除现有代码,并加入以下代码:
import Foundation
使用字符串虽然简单,但是也有一些重要的缺陷:
- 容易出错。任何不属于颜色规格的字符串都会正常编译,但是在运行时报错。
- Autocomplete不能正确的帮助你检测颜色名称。
- 当你传递一个颜色字符串参数时,它可能不能明确的表明这是一个代表颜色的字符串。
使用枚举来解决
使用自定义类型来解决这些问题。如果你来自Cocoa Touch,你可能想实现一个封装的类像UIColor。而Swift提供给您更多的选择来定义您的模型。
在实现这个功能之前,先让我们想想如何实现颜色enum,你可能会想到用以下代码来实现:
enum ColorName {
case Black
case Silver
case Gray
case White
case Maroon
case Red
// ... and so on ...
}
以上方式十分类似于C-style enums.然而,Swift允许你指定一个类型来表示每一个case。当然,被指定的类型必须遵守RawRepresentable协议。
所以你可以如下创建颜色枚举,并为每一个case赋值:
enum ColorName : String {
case Black = "Black"
case Silver = "Silver"
case Gray = "Gray"
case White = "White"
case Maroon = "Maroon"
case Red = "Red"
// ... and so on ...
}
Swift在使用字符串作为枚举值的时候有其特殊性。如果你没有制定case的值,那么编译器会自动为其赋值,值为case的名称。这意味着你可以像下面这样写:
enum ColorName : String {
case Black
case Silver
case Gray
case White
case Maroon
case Red
// ... and so on ...
}
你可以通过只写一次case并使用逗号来分割case来简化enum。
enum ColorName : String {
case Black, Silver, Gray, White, Maroon, Red, Purple, Fuchsia, Green, Lime, Olive, Yellow, Navy, Blue, Teal, Aqua
}
现在你在对于使用字符串来表示颜色所遇到的问题就解决了:
let fill = ColorName.Grey // ERROR: Misspelled color names won't compile. Good!
let fill = ColorName.Gray // Correct names autocomplete and compile. Yay!
关联值(Associated Values)
ColorName是命名Color的model。但是如果你希望像CSS中的那样可以有多种表现形式:名称,RGB, HSL 等等。如何为他们建模呢?
Swift中Enum对于建模十分强大,可以表现各种东西,如:CSS颜色,并且这些enum case与他们的值相关联。这些值成为关联值(Associated Values)
使用enum来定义CSSColor,向playground添加如下代码:
enum CSSColor {
case Named(ColorName)
case RGB(UInt8, UInt8, UInt8)
}
