枚举(Enumerations)通常称为“ enum”,发音为“ ee-num”,是一种在Swift中定义自己的值的方法。在某些编程语言中,它们只是简单的小事,但是Swift给它们增加了巨大的功能。
让我们从前面的一个简单示例开始:
代码语言:javascript复制func getHaterStatus(weather: String) -> String? {
if weather == "sunny" {
return nil
} else {
return "Hate"
}
}
该函数接受定义当前天气的字符串。问题是,对于这种类型的数据,字符串不是好的选择-是"rain'',“rainy''还是”raining''?还是“ showering(阵雨)”,“ drizzly(蒙蒙细雨)”或“ stormy(暴风雨)”?更糟糕的是,如果一个人用大写的R写下“ Rain”,而其他人却不在乎键入的内容,而又写下“ Ran”怎么办?
枚举通过让您定义一个新的数据类型,然后定义它可以容纳的可能值来解决此问题。例如,我们可以说有五种天气:sun, cloud, rain, wind 和 snow。如果我们将其设为枚举,则意味着Swift将仅接受这五个值-其他任何情况都会触发错误。在幕后,枚举通常只是简单的数字,比计算机使用的字符串要快得多。
让我们将其放入代码中:
代码语言:javascript复制enum WeatherType {
case sun, cloud, rain, wind, snow
}
func getHaterStatus(weather: WeatherType) -> String? {
if weather == WeatherType.sun {
return nil
} else {
return "Hate"
}
}
getHaterStatus(weather: WeatherType.cloud)
看一下前三行:第1行为我们的类型命名为WeatherType
。这就是您将在代码中代替String
或Int
的内容。正如我已经概述的那样,第2行定义了我们的枚举可能出现的五种情况。约定以小写字母开头,因此“ sun”,“ cloud”等。第3行只是一个大括号,结束了枚举。
现在看一下它的用法:我修改了getHaterStatus()
使其具有WeatherType
值。条件语句也被重写以与WeatherType.sun
进行比较,这是我们的值。请记住,此检查只是幕后的数字,闪电般快。
现在,返回并再次阅读该代码,因为我将通过两个重要的更改来重写它。
代码语言:javascript复制enum WeatherType {
case sun
case cloud
case rain
case wind
case snow
}
func getHaterStatus(weather: WeatherType) -> String? {
if weather == .sun {
return nil
} else {
return "Hate"
}
}
getHaterStatus(weather: .cloud)
我修改了两个地方。首先,每种天气类型现在都在单独一行。这似乎是一个很小的更改,在这个示例中确实如此,但是很快就变得很重要。第二个变化是我在weather == .sun
的情况下写的——我不需要拼写出完整的WeatherType.sun,因为Swift知道我正在与
WeatherType`变量进行比较,因此它使用类型推断。
枚举在switch / case
块内特别有用,特别是因为Swift知道您的枚举可以拥有的所有值,因此可以确保覆盖所有这些值。例如,我们可以尝试将getHaterStatus()
方法重写为:
func getHaterStatus(weather: WeatherType) -> String? {
switch weather {
case .sun:
return nil
case .cloud, .wind:
return "dislike"
case .rain:
return "hate"
}
}
是的,我意识到“ haters gonna dislike”并不是一个好主意,但无论如何它是学术性的,因为此代码无法构建因为它没有处理.snow
的case,Swift希望涵盖所有case。您要么为此添加一个案例,要么添加一个default:
。
带有附加值的枚举 (关联值枚举)
Swift最强大的功能之一是枚举可以具有您定义的附加值。为了进一步扩展这个越来越令人怀疑的示例,我将为.wind案例添加一个值,以便我们可以说风速有多快。修改您的代码为如下:
代码语言:javascript复制enum WeatherType {
case sun
case cloud
case rain
case wind(speed: Int)
case snow
}
如您所见,其他情况不需要速度值——我只是把它放在wind
中。现在是真正的魔力:Swift让我们在·switch / case·块中添加了附加条件,以便仅当这些条件为true时,case才会匹配。它使用let
关键字访问案例中的值,然后使用where
关键字进行模式匹配。
这是新函数:
代码语言:javascript复制func getHaterStatus(weather: WeatherType) -> String? {
switch weather {
case .sun:
return nil
case .wind(let speed) where speed < 10:
return "meh"
case .cloud, .wind:
return "dislike"
case .rain, .snow:
return "hate"
}
}
getHaterStatus(weather: WeatherType.wind(speed: 5))
您可以看到.wind
出现了两次,但是只有当风速低于每小时10公里时,第一次出现。如果风等于或大于10,则不会匹配。关键是您可以使用let
获取枚举中的值(即声明一个可以引用的常量名称),然后使用where
条件进行检查。
Swift会从上到下评估 switch/case
,并在找到匹配项后立即停止。这意味着,如果case .cloud,.wind:
出现在case .wind(let speed) where speed < 10:
之前,则将代替执行——同时输出更改。
因此,请仔细考虑如何给case排序!
提示:Swift的可选参数实际上是使用关联值枚举实现的。有两种情况:none
和some
,some
具有可选值内的值。
本文来自Hacking with Swift给swift初学者的入门课程Swift for Complete Beginners 的Optional Chaining
< Previous: 可选链 | Swift 入门 Home | Next: 结构体 > |
---|