从零开始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
}

var directionToHead = CompassPoint.west

当使用CompassPoint的某个可能值初始化directionToHead时, 推断其类型, 一旦directionToHead声明为CompassPoint, 我们可以使用较短的.语法将其设置为不同的CompassPoint值

directionToHead = .south
directionToHead = .east
directionToHead = .south

在switch中使用枚举

directionToHead = .south
switch directionToHead {
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"
}

隐式分配的原始值

当我们使用枚举存储整数或字符串原始值是, 不必为每种情况显式分配原始值. swift会自动分配值, 如果第一种情况没有设置值, 其值为0

下面的枚举是前面的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
        addition(ArithmeticExpression, ArithmeticExpression)
    indirect case
        multiplication(ArithmeticExpression, ArithmeticExpression)
}

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

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

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

let five = ArithmeticExpression.number(5)
let four = ArithmeticExpression.number(4)
let sum = ArithmeticExpression.addition(five, four)

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

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

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

你可能感兴趣的:(从零开始Swift之枚举)