枚举结构体

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")
        }
    }
 }