# 从零开始Swift之枚举

### 枚举

#### 枚举语法

enum SomeEnumeration {

}

#### eg 指南针上的四个主要的点

``````enum CompassPoint{
case north
case south
case east
case west
}
``````

### swift中约定俗成的枚举开头字母都是大写,而且不要使用复数形式

``````enum Planet{
case mercury, venus, earth, mars, jupiter, saturn, uranus, neptune
}

``````

``````directionToHead = .south
``````

### 在switch中使用枚举

``````directionToHead = .south
case .north:
print("Lots of planets have a north")
case .south:
print("Watch out for penguins")
case .east:
print("Where the sun rises")
case .west:
print("Where the skies are blue")
}
``````

### 原始值

#### 枚举可以预填充默认值,成为原始值,他们都是相同类型, 原始值可以是字符串，字符或任何整数或浮点数类型。每个原始值在其枚举声明中必须是唯一的

``````enum ASSCIIControlCharacter: Character{
case tab = "\t"
case lineFeed = "\n"
case carriageReturn = "\r"
}
``````

### 隐式分配的原始值

#### 下面的枚举是前面的Planet枚举的改进, 用整数原始值来表示每个行星的顺序

``````enum Planet: Int {
case mercury = 1, venus, earth, mars, jupiter, saturn, uranus, neptune
}
``````

#### 将CompassPoint枚举改为原始值为字符串

``````enum CompassPoint: String {
case north, south, east, west
}
``````

#### 可以使用rawValue属性访问枚举案例的原始值

``````let earthsOrder = Planet.earth.rawValue
// earthsOrder 的值为3

let sunsetDirection = CompassPoint.west.rawValue
// sunsetDirection的值为 "west"
``````

### 从原始值初始化

#### 如果使用原始值类型定义枚举, 则枚举会自动接收一个初始值, 改值包含原始值的类型(作为rawValue的参数), 并返回枚举或nil.我们可以使用初始化程序创建枚举的新实例

``````let possiblePlanet = Planet(rawValue: 7)
//possiblePlanet 的值为 uranus
``````

#### 如果你试图找到一个位置为11的行星，由原始值初始值器返回的可选Planet值将为nil：

``````let positionToFind = 11
if let somePlanet = Planet(rawValue: positionToFind) {
switch somePlanet {
case .earth:
print("Mostly harmless")
default:
print("Not a safe place for humans")
}
}else{
print("There isn't planet at position \(positionToFind)")
}
``````

### 递归枚举

#### 递归枚举是枚举的另一个枚举实例作为一个或多个枚举case的关联值, 我们通过在其前面写入indirect指示枚举情况是递归的, 这告诉编译器插入必要的间接层.

``````enum ArithmeticExpression {
case number(Int)
indirect case
indirect case
multiplication(ArithmeticExpression, ArithmeticExpression)
}
``````

#### 也可以将"indirect" 关键字写在"enum"前面

``````indirect enum ArithmeticExpression {
case number(Int)
case multiplication(ArithmeticExpression, ArithmeticExpression)
}
``````

#### 这个枚举可以存储三种算术表达式：一个普通数，两个表达式的加法和两个表达式的乘法。 加法和乘法情况具有也是算术表达式的关联值 - 这些关联值使得可以嵌套表达式。 例如，表达式（5 + 4）* 2在乘法的右手侧具有数字，在乘法的左手侧具有另一表达式。 因为数据是嵌套的，用于存储数据的枚举还需要支持嵌套 - 这意味着枚举需要递归。 下面的代码显示为（5 + 4）* 2创建的ArithmeticExpression递归枚举：“

``````let five = ArithmeticExpression.number(5)
let four = ArithmeticExpression.number(4)

let product = ArithmeticExpression.multiplication(sum, ArithmeticExpression.number(2))

func evaluate(_ expression: ArithmeticExpression) -> Int {
switch expression {
case let .number(value):
return value
return evaluate(left) + evaluate(right)
case let .multiplication(left, right):
return evaluate(left) * evaluate(right)
}
}

print(evaluate(product)) // 值为18
``````

### 推荐阅读更多精彩内容

• 本章将会介绍 闭包表达式尾随闭包值捕获闭包是引用类型逃逸闭包自动闭包枚举语法使用Switch语句匹配枚举值关联值原...
寒桥阅读 516评论 0 2
• 109.关联值 上部分实例展示枚举分支是一个定义值（类型值）。 你可以把一个常量或者变量设置成 Planet.ea...
无沣阅读 442评论 0 3
• 枚举为一组相关的值定义了一个共同的类型，使你可以在你的代码中以类型安全的方式来使用这些值。 如果你熟悉 C 语言，...
雨影阅读 43评论 0 0
• 枚举为一组相关的值定义了一个共同的类型，使得可以在代码中以类型安全的方式来使用这些值。 如果熟悉 C 语言，会知道...
穷人家的孩纸阅读 399评论 1 4
• 对文字，我已经疏懒到这个地步。好像已经忘记了发简书这回事。 现实中，有多少时间是拿来静静思考？我总是想把生活的常态...
若水无心一阅读 261评论 8 23