2015-07-21 开始更新 - 添加Recursive Enumerations

This commit is contained in:
futantan
2015-07-30 17:00:16 +08:00
parent 13eef04014
commit 462219eda6

View File

@ -10,6 +10,7 @@
- [匹配枚举值与`Swith`语句Matching Enumeration Values with a Switch Statement](#matching_enumeration_values_with_a_switch_statement)
- [相关值Associated Values](#associated_values)
- [原始值Raw Values](#raw_values)
- [递归枚举Recursive Enumerations](#recursive_enumerations)
枚举定义了一个通用类型的一组相关的值,使你可以在你的代码中以一个安全的方式来使用这些值。
@ -249,3 +250,60 @@ if let somePlanet = Planet(rawValue: positionToFind) {
这个范例使用可选绑定optional binding通过原始值`9`试图访问一个行星。`if let somePlanet = Planet(rawValue: 9)`语句获得一个可选`Planet`,如果可选`Planet`可以被获得,把`somePlanet`设置成该可选`Planet`的内容。在这个范例中,无法检索到位置为`9`的行星,所以`else`分支被执行。
<a name="recursive_enumerations"></a>
## 递归枚举Recursive Enumerations
Enumerations work well for modeling data when there is a fixed number of possibilities that need to be considered, such as the operations used for doing simple integer arithmetic. These operations let you combine simple arithmetic expressions that are made up of integers such as `5` into more complex ones such as `5 + 4`.
One important characteristic of arithmetic expressions is that they can be nested. For example, the expression `(5 + 4) * 2` has a number on the right hand side of the multiplication and another expression on the left hand side of the multiplication. Because the data is nested, the enumeration used to store the data also needs to support nesting—this means the enumeration needs to be recursive.
A recursive enumeration is an enumeration that has another instance of the enumeration as the associated value for one or more of the enumeration members. The compiler has to insert a layer of indirection when it works with recursive enumerations. You indicate that an enumeration member is recursive by writing indirect before it.
A `recursive enumeration` is an enumeration that has another instance of the enumeration as the associated value for one or more of the enumeration members. The compiler has to insert a layer of indirection when it works with recursive enumerations. You indicate that an enumeration member is recursive by writing `indirect` before it.
For example, here is an enumeration that stores simple arithmetic expressions:
```swift
enum ArithmeticExpression {
case Number(Int)
indirect case Addition(ArithmeticExpression, ArithmeticExpression)
indirect case Multiplication(ArithmeticExpression, ArithmeticExpression)
}
```
You can also write `indirect` before the beginning of the enumeration, to enable indirection for all of the enumerations members that need it:
```swift
indirect enum ArithmeticExpression {
case Number(Int)
case Addition(ArithmeticExpression, ArithmeticExpression)
case Multiplication(ArithmeticExpression, ArithmeticExpression)
}
```
This enumeration can store three kinds of arithmetic expressions: a plain number, the addition of two expressions, and the multiplication of two expressions. The `Addition` and `Multiplication` members have associated values that are also arithmetic expressions—these associated values make it possible to nest expressions.
A recursive function is a straightforward way to work with data that has a recursive structure. For example, heres a function that evaluates an arithmetic expression:
```swift
func evaluate(expression: ArithmeticExpression) -> Int {
switch expression {
case .Number(let value):
return value
case .Addition(let left, let right):
return evaluate(left) + evaluate(right)
case .Multiplication(let left, let right):
return evaluate(left) * evaluate(right)
}
}
// evaluate (5 + 4) * 2
let five = ArithmeticExpression.Number(5)
let four = ArithmeticExpression.Number(4)
let sum = ArithmeticExpression.Addition(five, four)
let product = ArithmeticExpression.Multiplication(sum, ArithmeticExpression.Number(2))
print(evaluate(product))
// prints "18"
```
This function evaluates a plain number by simply returning the associated value. It evaluates an addition or multiplication by evaluating the expression on the left hand side, evaluating the expression on the right hand side, and then adding them or multiplying them.