Swift入门:枚举

作者: 韦弦Zhy | 来源:发表于2020-03-16 22:05 被阅读0次

    \color{red}{\Huge \mathtt{SWIFT}}

    \color{orange}{\Large \mathbf{枚举}}

    \underline{\color{#3399CC}{\large \mathit{Enumerations}}}

    枚举(Enumerations)通常称为“ enum”,发音为“ ee-num”,是一种在Swift中定义自己的值的方法。在某些编程语言中,它们只是简单的小事,但是Swift给它们增加了巨大的功能。

    让我们从前面的一个简单示例开始:

    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将仅接受这五个值-其他任何情况都会触发错误。在幕后,枚举通常只是简单的数字,比计算机使用的字符串要快得多。

    让我们将其放入代码中:

    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。这就是您将在代码中代替StringInt的内容。正如我已经概述的那样,第2行定义了我们的枚举可能出现的五种情况。约定以小写字母开头,因此“ sun”,“ cloud”等。第3行只是一个大括号,结束了枚举。

    现在看一下它的用法:我修改了getHaterStatus()使其具有WeatherType值。条件语句也被重写以与WeatherType.sun进行比较,这是我们的值。请记住,此检查只是幕后的数字,闪电般快。

    现在,返回并再次阅读该代码,因为我将通过两个重要的更改来重写它。

    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案例添加一个值,以便我们可以说风速有多快。修改您的代码为如下:

    enum WeatherType {
        case sun
        case cloud
        case rain
        case wind(speed: Int)
        case snow
    }
    

    如您所见,其他情况不需要速度值——我只是把它放在wind中。现在是真正的魔力:Swift让我们在·switch / case·块中添加了附加条件,以便仅当这些条件为true时,case才会匹配。它使用let关键字访问案例中的值,然后使用where关键字进行模式匹配。

    这是新函数:

    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的可选参数实际上是使用关联值枚举实现的。有两种情况:nonesomesome具有可选值内的值。

    本文来自Hacking with Swift给swift初学者的入门课程Swift for Complete Beginners Optional Chaining

    < Previous: 可选链 Swift 入门 Home Next: 结构体 >

    赏我一个赞吧~~~

    相关文章

      网友评论

        本文标题:Swift入门:枚举

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