枚举结构体¶
1. 枚举¶
在实际的应用中,有的变量只有几种取值的选择。如人的性别至于两种取值(也有可能是三种),星期只有7种取值,其他的还有月份,颜色,学历,职位之类等。 在Swift语言种对这种取值比较特殊的变量,可以定义为枚举类型。所谓枚举类型是指将变量的值一一列举出来,并只限于在列举出来的值的范围内进行取值。 在程序设计语言中,一般用一个数值来代表某一状态,这种处理方法不直观,易读性差。如果能在程序中,用自然语言中的有相应含义的单词来代表某一状态,则程序就很容易阅读和理解。也就是说,事先考虑到某一变量的可能取值范围,尽量用自然语言中含义清楚的单词来表示它的每一个值,这种方法称为枚举方法,用这种方法定义的类型称为枚举类型。 在Swift语言中的枚举类型更加灵活,并且不须给枚举中的每一个成员提供值。在Swift中,枚举可以支持字符串,字符,整数和浮点类型,作为枚举成员的数据类型。
1.1 枚举语法¶
枚举的定义需要使用enum关键字,枚举的成员则被放置在一对大括号之中。
1 2 3 4 | enum 枚举名称
{
// 枚举定义放在这里
}
|
1.2 定义基本的枚举类型¶
加入我们需要指定游戏人物的运动方向,比如:上,下,左,右。我们就能够使用枚举来表述这一状态。
1 2 3 4 5 6 | enum Movement { case Top case Bottom case Left case Right } |
你可以,使用多种模式匹配结构获取到Movement的枚举值,或者按照特定的情况执行某个操作。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | let move = Movement.Left // switch 分情况处理 switch move { case .Left: print("Left") default: print("Other") } // 明确的case情况 if case .Left = move { print("Left") } if(move == .Left) { print("Left") } |
在上记案例中,我们无须明确指出enum的实际名称(即case Move.Left: print("Left"))。因为类型检查器能够自动为此进行类型推算。这对于那些UIKit以及AppKit中错综复杂的枚举是非常有用的。
1.3 枚举值¶
当然,你可能想要为enum中每个case分配一个值。这相当有用,比如枚举自身实际与某事或某物挂钩时,往往这些东西又需要使用不同类型来表述。在C语言中,你只能为枚举case分配整型值,而Swift则提供了更多的灵活性。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | // 映射到整型 enum Movement: Int { case Top = 0 case Bottom = 1 case Left = 2 case Right = 3 } // 同样你可以与字符串一一对应 enum House: String { case CZ = "常州" } // 或者float double都可以(同时注意枚举中的花式unicode) enum Constants: Double { case π = 3.14 case e = 2.71 } |
对于String和Int类型来说,你甚至可以忽略为枚举中的case赋值,Swift编译器也能正常工作。
1 2 3 4 5 6 7 8 9 10 11 12 | // Top = 0 enum Movement : Int { case Top } // Manager = "Manager" enum Level : String { case Manager } print(Movement.Top.rawValue) //输出结果为:0 print(Level.Manager.rawValue) //输出结果为:Manager |
Swift枚举中支持以下三种关联值类型:
- 整型(Int)
- 字符串(String)
- 浮点型(Float/Double)
因此你无法为枚举分配诸如:CGPoint类型的值。如果你想要获取枚举类型的值,可以使用**rawValue**属性来实现。 不过某种情形下,你可能想要通过一个已有的 rawvalue 来创建一个枚举实例。这种情况下,枚举提供了一个指定构造方法:
1 2 3 4 5 6 7 8 | enum Movement: Int { case Top = 0 case Bottom = 1 case Left = 2 case Right = 3 } // 创建一个movement.Top 用例,其rawvalue值为0 let right = Movement(rawValue: 0) |
1.4 嵌套枚举¶
如果你有特定子类型的需求,可以对enum进行嵌套。这样就允许你为实际的enum中包含其他明确信息的enum。 以坦克大战游戏中的每个角色为例,每个角色能够拥有子弹类型,当前移动方向。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | enum Tank { // 子弹类型 enum Bullet { case Shotgun case fire } // 移动方向 enum Movement { case Top case Bottom case Left case Right } case Enemy case Friendly } |
现在,你可以通过层级结构来进行描述。
1 2 3 | let enemyTank = Tank.Enemy let bullet = Tank.Bullet.Shotgun let movement = Tank.Movement.Top |
1.5 包含枚举¶
同样地,你也能够在struct或class中内嵌枚举。同样地,这也将有助于我们将相关的信息集中在一个位置。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | struct Tank { // 子弹类型 enum Bullet { case Shotgun case fire } // 移动方向 enum Movement { case Top case Bottom case Left case Right } let bullet: Bullet let movement: Movement } let tank = Tank(bullet: .fire, movement: .Top) |
1.6 元组参数¶
在枚举中,我们可能需要给每一个case指定一系列的参数,如下记代码所示,股票交易的时候,可以执行名称和数量。
1 2 3 4 5 | typealias config = (String, Int) enum Trade { case Buy(config) } |
当我们需要给枚举设定值时,可以采用下面的方式进行设定。
1 2 3 4 5 6 7 | let tp = ("APPL", 10000) let trade = Trade.Buy(tp) // 通过这种方式,对股票信息进行查询 if case let .Buy(stock, amount) = trade { print("\(stock)") } |
1.7 枚举中添加方法¶
1 2 3 4 5 6 7 8 9 10 11 12 | enum Movement { case Top case Bottom func description() { switch self { case .Top: print("Top") default: print("Other") } } } |