枚举是许多编程语言中的常见设计模式。 尽管您可能熟悉C和Objective-C中的枚举,但是Swift的枚举实现更加强大和灵活。 在此快速提示中,您将学习Swift中的枚举的特殊之处,如何在项目中使用它们以及使它们如此强大的原因。
1.什么是枚举?
枚举并不是新事物,而且对于Swift来说肯定不是唯一的。 但是,如果您熟悉C中的枚举,那么您会喜欢Swift强大的枚举方法。
如果您不熟悉枚举或枚举,那么您可能不熟悉它们所提供的功能。 在Swift中,枚举是第一类类型,它定义了该类型的可能值的列表。
一个示例可能是网络连接的可能状态。 可能的状态可能是:
- 断开连接
- 连接中
- 连接的
如果状态未知,我们可以添加第四个状态。 考虑到此示例,让我们看看如何定义和实现这样的枚举。
基本
就像我说的那样,枚举是Swift中的一流类型。 枚举定义看起来与类或结构定义非常相似。 在下面的示例中,我们定义ConnectionState
枚举。
enum ConnectionState {
}
枚举的名称前面带有enum
关键字,后跟一对花括号。 ConnectionState
枚举将定义网络连接的可能状态。 要定义这些状态,我们将成员值或成员添加到枚举的定义中。 成员值的定义始终以case
关键字开头。
enum ConnectionState {
case Unknown
case Disconnected
case Connecting
case Connected
}
在C或Objective-C中,如下面的示例所示,上面的枚举看起来有些不同。 枚举的每个值都对应一个整数,例如, ConnectionStateUnknown
等于0
, ConnectionStateDisconnected
等于1
,等等。
typedef enum : NSUInteger {
ConnectionStateUnknown,
ConnectionStateDisconnected,
ConnectionStateConnecting,
ConnectionStateConnected
} ConnectionState;
在Swift中并非如此。 枚举的成员不会自动与整数值相对应。 ConnectionState
枚举的成员本身就是值,它们的类型为ConnectionState
。 这使得使用枚举更安全,更明确。
原始值
可以显式指定枚举成员的值。 在以下示例中, ConnectionState
枚举的成员的原始值为Int
类型。 为每个成员分配一个原始值,该值对应一个整数。
enum ConnectionState: Int {
case Unknown = -1
case Disconnected = 0
case Connecting = 1
case Connected = 2
}
请注意,我们在枚举的定义中指定了原始值的类型,并且没有两个成员值可以具有相同的原始值。 如果我们仅为Unknown
成员指定一个值,则Swift将自动递增Unknown
成员的值,并将唯一值分配给枚举的其他成员。 为了更好地说明这一点,下面的示例与ConnectionState
枚举的先前定义相同。
enum ConnectionState: Int {
case Unknown = -1
case Disconnected
case Connecting
case Connected
}
2.使用枚举
初始化
使用ConnectionState
枚举类似于在Swift中使用任何其他类型。 在下一个示例中,我们声明一个变量connectionState
,并将其值设置为ConnectionState.Connecting
。
var connectionState = ConnectionState.Connecting
connectionState
值为ConnectionState.Connecting
,变量的类型为ConnectionState
。
使用枚举时,Swift的类型推断非常方便。 因为我们将connectionState
声明为ConnectionState
类型,所以我们现在可以通过使用枚举的速记点语法来分配新值。
connectionState = .Connected
控制流
在if
或switch
语句中使用枚举很简单。 请记住, switch
语句需要详尽无遗。 如有必要,添加default
案例。
enum ConnectionState {
case Unknown
case Disconnected
case Connecting
case Connected
}
var connectionState = ConnectionState.Connecting
connectionState = .Connected
switch connectionState {
case .Disconnected:
println("Disconnected")
case .Connecting:
println("Connecting")
case .Connected:
println("Connected")
default:
println("Unknown State")
}
下面的示例演示如何使用ConnectionState
枚举。 它还显示了如何访问枚举成员的关联值。 canConnect
函数接受ConnectionState
实例并返回Bool
。
func canConnect(connectionState: ConnectionState) -> Bool {
var result = false
switch connectionState {
case .Connected(let port):
if port == 3000 {
result = true
}
default:
result = false
}
return result
}
let state = ConnectionState.Connected(3000)
if canConnect(state) {
// ...
}
仅当传递给函数的ConnectionState
实例等于.Connected
并且其关联值是等于3000
的Int
, canConnect
函数才返回true
。 请注意, Connected
成员的关联值在switch
语句中可作为名为port
的常量使用,然后可以在相应的case
。
3.关联价值
Swift枚举的另一个引人注目的功能是关联值。 枚举的每个成员可以具有关联的值。 关联值非常灵活。 例如,同一枚举的不同成员的关联值不必为同一类型。 请看以下示例,以更好地理解关联值的概念。
enum ConnectionState {
case Unknown
case Disconnected
case Connecting(Int, Double)
case Connected(Int)
}
Unknown
和Disconnected
成员没有关联的值。 Connecting
成员的关联值类型为(Int, Double)
,用于指定连接的端口号和超时间隔。 Connected
成员具有一个Int
类型的关联值,用于指定端口号。
重要的是要了解关联的值已与枚举的成员链接或相关联。 会员的价值保持不变。 下一个示例说明如何创建具有关联值的ConnectionState
实例。
var connectionState = ConnectionState.Connecting(3000, 30.0)
4.方法和值类型
方法
枚举在Swift中非常强大。 枚举甚至可以定义方法,例如初始化程序,以在未指定默认成员值的情况下选择默认成员值。
enum ConnectionState {
case Unknown
case Disconnected
case Connecting(Int, Double)
case Connected(Int)
init () {
self = .Unknown
}
}
var connectionState = ConnectionState() // .Unknown
在此示例中,我们初始化了ConnectionState
枚举的实例,而没有为其显式指定值。 但是,在枚举的初始化程序中,我们将实例设置为Unknown
。 结果是connectionState
变量等于ConnectionState.Unknown
。
值类型
像结构一样,枚举是值类型,这意味着枚举不像类实例那样通过引用传递,而是通过值传递。 以下示例说明了这一点。
var connectionState1 = ConnectionState()
var connectionState2 = connectionState1
connectionState1 = .Connected(1000)
println(connectionState1) // .Connected(1000)
println(connectionState2) // .Unknown
即使我们将connectionState1
分配给connectionState2
,在示例末尾, connectionState1
和connectionState2
的值也不同。
将connectionState1
分配给connectionState2
,Swift将创建connectionState1
的副本并将其分配给connectionState2
。 换句话说, connectionState1
和connectionState2
引用两个不同的ConnectionState
实例。
结论
与C语言中的枚举相比,Swift中的枚举具有令人难以置信的强大功能。枚举最强大的方面之一是它们是Swift中的一流类型。 类型安全性是Swift语言的关键方面,枚举完全符合这种思维方式。
翻译自: https://code.tutsplus.com/tutorials/quick-tip-enumerations-in-swift--cms-23205