Swift中的枚举(或简称枚举)为一组相关的值定义了一个共同的类型。根据Swift文档,枚举使你能够在你的代码中以类型安全的方式处理这些值。当你有很多不同的选项需要编码的时候,枚举就显得特别方便了。
在Swift中使用enum ,类似于编写代码,在满足条件时返回一个布尔值--例如,true 或false 。然而,在枚举的情况下,你可以有两个以上的可能值。
把一个枚举想象成一个恒温器。有一个可能匹配结果的数值范围--例如,低、中、高、极端。根据被匹配的情况,我们要运行一些指定的代码。
枚举是一种特殊类型的变量,专门用于开关和条件式。Swift的枚举情况没有唯一的默认整数值(像一个数组),不像TypeScript和Objective C等语言,第一个元素的值是0 ,第二个元素的值是1 ,以此类推。
在本教程中,我们将介绍Swift枚举的所有基础知识,包括。
- Swift枚举的语法
[CaseIterable](#caseiterable-in-enumeration-cases)在枚举的情况下- 枚举的原始值
- 枚举关联值
- 枚举方法
- 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,left 和right --被称为枚举的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 方法中使用开关语句,根据星期几返回Weekend 或Weekday 作为输出。
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博客上。