天天看点

8.枚举

  枚举为一组相关的值定义了一个共同的类型,使你可以在你的代码中以类型安全的方式来使用这些值。Swift 中的枚举更加灵活,不必给每一个枚举成员提供一个值。如果给枚举成员提供一个值(称为“原始”值),则该值的类型可以是字符串,字符,或是一个整型值或浮点数。

1.枚举语法

enum SomeEnumeration {
    // 枚举定义放在这里
}      

  示例: 

enum CompassPoint {
    case North;
    case South;
    case East;
    case West;
};

//多个成员值在同一行
enum CompassPoint2 {
    case North, South, East, West;
};

var directionToHead : CompassPoint = .West;

//【说明】:
//1.使用case关键字来定义一个新的枚举成员值。
//2.Swift 的枚举成员在被创建时不会被赋予一个默认的整型值。在上面的例子中,North,South,East和West不会被隐式地赋值为0,1,2和3。相反,这些枚举成员本身就是完备的值,这些值的类型是已经明确定义好的CompassPoint类型。
//3.多个成员值可以出现在同一行上,用逗号隔开。
//4.当枚举类型已知时,为其赋值可以省略枚举类型名。      

2.使用 Switch 语句匹配枚举值

enum CompassPoint {
    case North, South, East, West;
};

var directionToHead : CompassPoint = .West;
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");
}      

3.关联值 

enum Barcode
 {
    case UPCA(numberSystem: Int, manufacturer: Int, product: Int, check: Int);
    case QRCode(productCode: String);
 }
 
 var productBarcode = Barcode.UPCA(numberSystem: 8, manufacturer: 85909, product: 51226, check: 3);
// productBarcode = .QRCode(productCode: "GofLee");
 
 switch productBarcode
 {
 case .UPCA(let numberSystem, let manufacturer, let product, let check):  //关联值作为常量
    print("UPC-A: \(numberSystem), \(manufacturer), \(product), \(check).");
    
 case .QRCode(var productCode):  //关联值作为变量
    print("QR code: \(productCode).")
 }
 
 //【说明】:Barcode类型的常量和变量可以存储一个.UPCA或者一个.QRCode(连同它们的关联值),但是在同一时间只能存储这两个值中的一个。      

4.原始值 

enum ASCIIControlCharacter: Character
{
    case Tab = "\t";
    case LineFeed = "\n";
    case CarriageReturn = "\r";
}

//【说明】:
//1.原始值(默认值)的类型必须相同,并且是必须显示指定;
//2.对于一个特定的枚举成员,它的原始值始终不变。关联值是创建一个基于枚举成员的常量或变量时才设置的值,枚举成员的关联值可以变化。

//进化1:在使用原始值为整数或者字符串类型的枚举时,不需要显式地为每一个枚举成员设置原始值,Swift 将会自动赋值。
enum Planet: Int {
    case Mercury = 1, Venus, Earth, Mars, Jupiter, Saturn, Uranus, Neptune
}

enum Seasons: String {
    case Spring, Summer, Autumn, Winter
}
//【说明】:Planet.Venus的隐式原始值为2;Seasons.Summer的隐式原始值Summer。

// TODO: 使用示例:使用原始值初始化枚举实例
let possiblePlanet = Planet(rawValue: 7);
//【说明】:如果在定义枚举类型的时候使用了原始值,那么将会自动获得一个初始化方法,这个方法接收一个叫做rawValue的参数,参数类型即为原始值类型,返回值则是枚举成员或nil。      

5.递归枚举

  • 递归枚举(recursive enumeration)是一种枚举类型,它有一个或多个枚举成员使用该枚举类型的实例作为关联值。使用递归枚举时,编译器会插入一个间接层。你可以在枚举成员前加上indirect来表示该成员可递归。 
enum ArithmeticExpression
{
    case Number(value: Int);
    indirect case Addition(expressionOne: ArithmeticExpression, expressionTwo: ArithmeticExpression);
    indirect case Multiplication(expressionOne: ArithmeticExpression, expressionTwo: ArithmeticExpression);
}

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

// 计算 (5 + 4) * 2
let five = ArithmeticExpression.Number(value: 5);
let four = ArithmeticExpression.Number(value: 4);
let sum = ArithmeticExpression.Addition(expressionOne: five, expressionTwo: four);
let product = ArithmeticExpression.Multiplication(expressionOne: sum, expressionTwo: ArithmeticExpression.Number(value: 2));
print(evaluate(product));  // 输出 "18"      

无善无恶心之体,

有善有恶意之动,

知善知恶是良知,

为善去恶是格物。

上一篇: 6.函数
下一篇: 7.闭包

继续阅读