快速提示:Swift中的枚举

枚举是许多编程语言中的常见设计模式。 尽管您可能熟悉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等于0ConnectionStateDisconnected等于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

控制流

ifswitch语句中使用枚举很简单。 请记住, 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并且其关联值是等于3000IntcanConnect函数才返回true 。 请注意, Connected成员的关联值在switch语句中可作为名为port的常量使用,然后可以在相应的case

3.关联价值

Swift枚举的另一个引人注目的功能是关联值。 枚举的每个成员可以具有关联的值。 关联值非常灵活。 例如,同一枚举的不同成员的关联值不必为同一类型。 请看以下示例,以更好地理解关联值的概念。

enum ConnectionState {
    case Unknown
    case Disconnected
    case Connecting(Int, Double)
    case Connected(Int)
}

UnknownDisconnected成员没有关联的值。 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 ,在示例末尾, connectionState1connectionState2的值也不同。

connectionState1分配给connectionState2 ,Swift将创建connectionState1的副本并将其分配给connectionState2 。 换句话说, connectionState1connectionState2引用两个不同的ConnectionState实例。

结论

与C语言中的枚举相比,Swift中的枚举具有令人难以置信的强大功能。枚举最强大的方面之一是它们是Swift中的一流类型。 类型安全性是Swift语言的关键方面,枚举完全符合这种思维方式。

翻译自: https://code.tutsplus.com/tutorials/quick-tip-enumerations-in-swift--cms-23205

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值