Swift枚举。带例子的概述

218 阅读7分钟

Swift中的枚举(或简称枚举)为一组相关的值定义了一个共同的类型。根据Swift文档,枚举使你能够在你的代码中以类型安全的方式处理这些值。当你有很多不同的选项需要编码的时候,枚举就显得特别方便了。

在Swift中使用enum ,类似于编写代码,在满足条件时返回一个布尔值--例如,truefalse 。然而,在枚举的情况下,你可以有两个以上的可能值。

把一个枚举想象成一个恒温器。有一个可能匹配结果的数值范围--例如,低、中、高、极端。根据被匹配的情况,我们要运行一些指定的代码。

枚举是一种特殊类型的变量,专门用于开关和条件式。Swift的枚举情况没有唯一的默认整数值(像一个数组),不像TypeScript和Objective C等语言,第一个元素的值是0 ,第二个元素的值是1 ,以此类推。

在本教程中,我们将介绍Swift枚举的所有基础知识,包括。

Swift 枚举的语法

要在Swift中定义一个枚举,请使用关键字enum ,后面跟着枚举的名称。Swift中枚举的名称应该遵循PascalCase的命名惯例,即复合词中每个词的第一个字母都要大写。

// starts with the keyword 'enum'and follows the PascalCase naming convention
enum EnumerationNmae {
    // our enum values (case) goes in here
  }

下面我们来仔细看看如何在枚举中声明数值。

enum Direction {
    case up
    case down
    case left
    case right
}

在枚举中声明的值--up,down,leftright --被称为枚举的case。我们使用case关键字来引入一个新的枚举情况。

相对于if-else 语句而言,枚举在switch 语句中特别有用。这是因为在switch语句中,Swift知道枚举所拥有的所有值,所以它会确保你的枚举涵盖所有的情况,或者添加一个默认的情况。

枚举情况下的CaseIterable

CaseIterable 是一种类型,它提供了一个枚举所有值的集合。它被用来遍历一个枚举中的所有情况。

要做到这一点,请在枚举的名称后面添加CaseIterable 。这样一来,Swift就可以通过枚举类型上的一个名为allCases 的属性,让我们访问所有情况的集合。

enum CarBrand: String, CaseIterable {
    case Mercedes = "Known for luxury and iconic design. Definitely my fav!"
    case Toyota = "Known for high-quality, high-value cars"
    case Volkswagen = "This is the people's car"
    case Ford = "Known for crisp handling, absorbent ride, and solid feel"
    case Honda = "Known for their well-built, reliable cars"
}

要访问我们的CarBrand 枚举中的所有情况的集合,我们可以这样做。

print(CarBrand.allCases.count)
// expected output: 5

在上面的例子中,我们写了CarBrand.allCases ,以访问一个包含CarBrand 枚举中所有情况的集合。count 方法给出了我们集合中元素的数量。

我们可以通过使用for 循环访问我们枚举中的所有情况,从而更进一步。

让我们使用allCases 方法打印把原始值放在我们的枚举案例中。

// create an enum with a CaseIterable type

enum CarBrand: String, CaseIterable {
    case Mercedes = "Known for luxury and iconic design. Definitely my fav!"
    case Toyota = "Known for high-quality, high-value cars"
    case Volkswagen = "This is the people's car"
    case Ford = "Known for crisp handling, absorbent ride, and solid feel"
    case Honda = "Known for their well-built, reliable cars"
}

// we are looping through our enum and accessing all its raw values
for brand in CarBrand.allCases {
    print(brand.rawValue)
}
// expected output:
// Known for luxury and iconic design. Definitely my fav!
// Known for high-quality, high-value cars
// This is the people's car
// Known for crisp handling, absorbent ride, and solid feel
// Known for their well-built, reliable cars

枚举的原始值

在我们的枚举中,我们可以声明一个原始值类型。这本质上意味着将一个值附加到枚举案例中。

为了更好地理解枚举中的原始值,让我们创建一个字符串类型的枚举(它可以是任何类型)来保存不同品牌的汽车以及每个品牌已知的属性(这些将是原始值)。

// Enum with raw values

enum CarBrand: String {
    case Mercedes = "Known for luxury and iconic design. Definitely my fav!"
    case Toyota = "Known for high-quality, high-value cars"
    case Volkswagen = "This is the people's car"
    case Ford = "Known for crisp handling, absorbent ride, and solid feel"
    case Honda = "Known for their well-built, reliable cars"
}

为了给你的枚举设置一个值,你需要给它指定一个数据类型。在我们上面的案例中,我们使用的类型是String

我们的枚举情况的每个原始值必须是一个唯一的字符串、字符或任何整数或浮点类型的值。这意味着两个case语句的值不能相同。请看下面的代码。

enum CarBrand: String {
    case Toyota = "High value cars."
    case Volkswagen = "High value cars."
}

上面的代码抛出了一个错误:"Raw value for enum case is not unique",因为两个case的值完全相同。

现在我们已经创建了我们的枚举,每个枚举案例都有一个原始值,让我们创建一个函数来返回各种汽车品牌的rawValue 。这里的原始值代表了每个品牌已知的属性。

func carKnownFor(brand: CarBrand) -> String {
    return brand.rawValue
} 

carKnownFor(brand: .Ford)
carKnownFor(brand: .Mercedes)

// expected output: 
// "Known for luxury and iconic design. Definitely my fav!"
// "Known for crisp handling, absorbent ride, and solid feel"

枚举关联值

Swift中枚举的一个最好的特点是,你可以让你定义的值附加到每个case 中的枚举。这使你能够为你的枚举附加额外的信息,以便它们能够代表更有意义的数据。

例如,假设我们有一个枚举,定义了奔驰汽车的价格。根据价格,我们想确定一个用户是否能买得起这个型号的汽车。我们可以在我们的enum 中把价格和汽车的品牌联系起来,就像我们在下面的例子中一样。

// enum with associated values
enum MercedesModelPrice {
   case MayBach(price: Int)
   case AMG_GT(price: Int)
   case Metris(price: Int)
   case SprinterWagon(price: Int)
   case GClass
}
// enum without associated values 
enum MercedesModelPrice {
   case MayBach
   case AMG_GT
   case Metris
   case SprinterWagon
   case GClass
}

现在,让我们创建一个函数来检查用户是否能买得起奔驰车。

func getMercedesPrice(for mercedesModel: MercedesModelPrice) {
   switch mercedesModel {
   case .MayBach(price: let price) where price >= 100_000:
    print("You just bought yourself a new car")

   case .Metris(price: let price) where price >= 86_000:
    print("You just bought yourself a new car")

   case .AMG_GT(price: let price)  where price >= 74_000:
    print("You just bought yourself a new car")

   case .SprinterWagon(price: let price) where price >= 45_000:
     print("You just bought yourself a new car")

   case .GClass, .SprinterWagon, .Metris, .AMG_GT, .MayBach:
    print("Insufficient funds. You cant' afford this car at the moment")

   }
}

// Calling our function
getMercedesPrice(for: .SprinterWagon(price: 200_000))
// expected output: You just bought yourself a new car

请注意我们是如何使用where 关键字来过滤case 的特定价格的。

值得注意的是,case 语句的顺序很重要。把最后一个case 语句(case .GClass, .SprinterWagon, .Metris, .AMG_GT, .MayBach:)放在前面,意味着我们总是会得到附加在这个案例上的结果,作为一个匹配。

枚举方法

除了在我们的枚举中定义枚举案例,我们还可以在我们的enum 中定义方法,像这样。

enum Weekday {
    case Monday
    case Tuesday
    case Wednesday
    case Thursday
    case Friday
    case Saturday
    case Sunday

    func dayType() -> String {
        switch self {
        case .Sunday, .Saturday:
            return  "Weekend"
        default:
            return "Weekday"
        }
     }
}


Weekday.Monday.dayType()
// this will return "Weekday"
Weekday.Sunday.dayType()
// this will return "Weekend"

在上面的代码片断中,我们在dayType 方法中使用开关语句,根据星期几返回WeekendWeekday 作为输出。

Swift枚举中的计算属性

你也可以使用枚举中的计算属性来代替函数。

让我们用一个计算属性来代替我们上面代码中的dayType 函数。

enum Weekday {
    case Monday
    case Tuesday
    case Wednesday
    case Thursday
    case Friday
    case Saturday
    case Sunday

    var dayType: String {
        self == .Saturday || self == .Sunday ? "Weekend" : "Weekday"
    }

}

Weekday.Monday.dayType
// this will return "Weekday"
Weekday.Sunday.dayType
// this will return "Weekend"
>

结论

Swift 枚举可以成为简化代码的一种强大方式。在本教程中,我们介绍了enums 的语法和如何定义它们,如何创建枚举案例,以及如何在switch 语句中使用它们。我们还定义了CaseIterable ,它是一个提供枚举所有值的集合的类型。我们涵盖了枚举值(包括原始值和关联值)以及如何在我们的代码库中使用它们。最后,我们演示了如何使用Swift枚举中的计算属性来代替函数。

The postSwift enums:带例子的概述》首先出现在LogRocket博客上。