Swift4.2_枚举

作者: 鼬殿 | 来源:发表于2018-11-30 15:35 被阅读27次

官网链接

枚举为一组相关值定义了一个公共类型,使您能够在代码中以类型安全的方式处理这些值。

如果您熟悉C,您将知道C枚举将相关名称分配给一组整数值。 Swift中的枚举更加灵活,并且不必为枚举的每个案例提供值。 如果为每个枚举情况提供了一个值(称为“原始”值),则该值可以是字符串,字符或任何整数或浮点类型的值。

Swift中,枚举是一等类型,可以提供一些在其他语言中类对象才有的特性。

  • 枚举语法 (Enumeration Syntax)

使用enum关键字引入枚举,并将其整个定义放在一对大括号中:

enum SomeEnumeration {
    // enumeration definition goes here
}

以下是指南针的四个要点的示例:

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

case关键字明确了要定义的枚举成员值(相当于定义变量时使用的var关键字,定义枚举成员值则使用关键字case)。与C语言不同的是,这些变量并没有被定义成0,1,2,3这些整型值。

多个成员值可以在同一行,用逗号隔开。

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

每个枚举定义都定义了一个新类型。 与Swift中的其他类型一样,它们的名称(例如CompassPointPlanet)应该以大写字母开头。 给出枚举类型单数而不是复数名称,以便它们看起来不言自明:

var directionToHead = CompassPoint.west

此时我们已经知道directionToHead是一个CompassPoint类型了,如果需要改变值,可以省略CompassPoint

directionToHead = .east
  • 使用Switch语句匹配枚举值 (Matching Enumeration Values with a Switch Statement)

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")
}
// Prints "Watch out for penguins"

如控制流程中所述,在考虑枚举的情况时,switch语句必须是详尽的。 如果省略.west的情况,则此代码不会编译,因为它不考虑CompassPoint案例的完整列表。 要求详尽无遗确保枚举案例不会被意外遗漏。

如果不适合为每个枚举提供案例,可以提供一个默认案例:

let somePlanet = Planet.earth
switch somePlanet {
case .earth:
    print("Mostly harmless")
default:
    print("Not a safe place for humans")
}
// Prints "Mostly harmless"
  • 遍历枚举用例 (Iterating over Enumeration Cases)

对于某些枚举,拥有所有枚举的案例集合很有用。 您可以通过在枚举名称后写入:CaseIterable来启用此功能。 Swift将所有案例的集合公开为枚举类型的allCases属性。 这是一个例子:

enum Beverage: CaseIterable {
    case coffee, tea, juice
}
let numberOfChoices = Beverage.allCases().count
print("\(numberOfChoices) beverages available")
// Prints "3 beverages available"

遍历枚举

for beverage in Beverage.allCases() {
    print(beverage)
}
// coffee
// tea
// juice
  • 关联值 (Associated Values)

枚举成员值可以不关联同一种类型的值,也就是说,枚举中的每个成员都可以设置不同的关联值。

举个例子,定义一个条码枚举,里面有二维码和条形码两种类型,这两种类型关联的值不同,可以这样定义。

enum Barcode {
    case upc(Int, Int, Int, Int)
    case qrCode(String)
}
使用如下:
var productBarcode = Barcode.upc(8, 85909, 51226, 3)
productBarcode = .qrCode("ABCDEFGHIJKLMNOP")

也可以使用switch的值绑定

switch productBarcode {
case .upc(let numberSystem, let manufacturer, let product, let check):
    print("UPC: \(numberSystem), \(manufacturer), \(product), \(check).")
case .qrCode(let productCode):
    print("QR code: \(productCode).")
}
// Prints "QR code: ABCDEFGHIJKLMNOP."

如果枚举案例的所有关联值都被提取为常量,或者如果所有关联值都被提取为变量,则可以在案例名称前放置单个varlet注释,以简洁起见:

switch productBarcode {
case let .upc(numberSystem, manufacturer, product, check):
    print("UPC : \(numberSystem), \(manufacturer), \(product), \(check).")
case let .qrCode(productCode):
    print("QR code: \(productCode).")
}
// Prints "QR code: ABCDEFGHIJKLMNOP."
  • 原始值 (Raw Values)

“关联值”中的条形码示例显示了枚举的情况如何声明它们存储了不同类型的关联值。 作为关联值的替代,枚举情况可以预先填充默认值(称为原始值),它们都是相同的类型。

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

1.隐式分配原始值 (Implicitly Assigned Raw Values)

当你在操作存储整数或字符串原始值枚举的时候,你不必显式地给每一个成员都分配一个原始值。当你没有分配时,Swift 将会自动为你分配值。

实际上,当整数值被用于作为原始值时,每成员的隐式值都比前一个大一。如果第一个成员没有值,那么它的值是0

下面的枚举是先前的Planet枚举的简化,用整数原始值来代表从太阳到每一个行星的顺序

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

隐式指定string原始值

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

您可以使用其rawValue属性访问枚举大小写的原始值:

let earthsOrder = Planet.earth.rawValue
// earthsOrder is 3

let sunsetDirection = CompassPoint.west.rawValue
// sunsetDirection is "west"

2.使用原始值初始化 (Initializing from a Raw Value)

如果你用原始值类型来定义一个枚举,那么枚举就会自动收到一个可以接受原始值类型的值的初始化器(叫做 rawValue的形式参数)然后返回一个枚举成员或者 nil 。你可以使用这个初始化器来尝试创建一个枚举的新实例。

let possiblePlanet = Planet(rawValue: 7)
// possiblePlanet is of type Planet? and equals Planet.uranus

如果您尝试查找位置为11的行星,则原始值初始值设定项返回的可选行星值将为零:

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 a planet at position \(positionToFind)")
}
// Prints "There isn't a planet at position 11"
  • 递归枚举 (Recursive Enumerations)

递归枚举是枚举,它将枚举的另一个实例作为一个或多个枚举个案的关联值。 您通过在其之前写入indirect来指示枚举情况是递归的,这告诉编译器插入必要的间接层。

例如,这是一个存储简单算术表达式的枚举:

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

也可以把indirect写在外面,自动判断成员变量在需要递归的时候递归

indirect enum ArithmeticExpression {
    case number(Int)
    case addition(ArithmeticExpression, ArithmeticExpression)
    case multiplication(ArithmeticExpression, 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))
// Prints "18"

相关文章

  • Swift4.2_枚举

    官网链接 枚举为一组相关值定义了一个公共类型,使您能够在代码中以类型安全的方式处理这些值。 如果您熟悉C,您将知道...

  • Swift4.2_函数

    官网链接 Swift中的每个函数都有一个类型,由函数的参数类型和返回类型组成。 您可以像Swift中的任何其他类型...

  • Swift4.2_属性

    官网链接 属性将值与特定类,结构或枚举相关联。 存储属性将常量和变量值存储为实例的一部分,而计算属性则计算(而不是...

  • Swift4.2_ 方法

    官网链接 方法是与特定类型相关联的函数。类、结构和枚举都可以定义实例方法,这些方法封装用于处理给定类型的实例的特定...

  • C#枚举及与枚举常数的转换

    1、枚举的定义 2、枚举绑定到comboBox 3、枚举常数转换为枚举string转枚举 数字值转枚举

  • Swift 基础笔记 - 枚举

    枚举 OC定义和使用枚举 Swift定义枚举类型 Swift判断枚举类型 枚举成员类型

  • Swift4.2_闭包

    官网链接 闭包是自包含的功能块,可以在代码中传递和使用。 Swift中的闭包类似于C和Objective-C中的块...

  • Swift4.2_集合类型

    官网链接 数组 (Arrays) 1.创建一个空的数组 2.创建具有默认值的数组 3.将两个数组加起来,创建一个新...

  • Swift4.2_控制流

    官网链接 For-In循环 ( For-In Loops) 使用for-in循环遍历序列,例如数组中的项、数字范围...

  • 枚举类

    1.枚举类型的定义: 枚举类型定义的一般形式为 enum 枚举名{//枚举值表枚举值1;枚举值2;...} 在枚举...

网友评论

    本文标题:Swift4.2_枚举

    本文链接:https://www.haomeiwen.com/subject/eoqhcqtx.html