swift枚举_Swift:枚举

swift枚举

如何在Swift中正确建模数据 (How to correctly model data in Swift)

In this article, we’re going to learn about enumerations in Swift or as they’re more commonly known, enums.

在本文中,我们将学习Swift中的enumerations或更广为人知的枚举

An enumeration defines a common type for a group of related values and enables you to work with those values in a type-safe way within your code — swift.org

枚举为一组相关值定义了通用类型,并使您能够在代码中以类型安全的方式使用这些值— swift.org

Enumerations are used to model a finite dataset and found commonly in different programming languages. In Swift its history can be traced back to C language but enumerations in Swift are a lot more flexible.

Enumerations 用于对有限数据集进行建模,并通常在不同的编程语言中找到。 在Swift中,其历史可以追溯到C语言,但是Swift中的enumerations更加灵活。

为什么枚举:问题 (Why Enumerations: the problem)

Swift offers multiple ways to model data to be used in a program. We can use object and collections to do that. But there is certain kinds of data where normal objects and collections don’t quite suffice the need.

Swift提供了多种方法来对要在程序中使用的数据进行建模。 我们可以使用对象和集合来做到这一点。 但是在某些类型的数据中,普通objectscollections不能满足需要。

Enumerations are extensively used to represent fixed set of values.

Enumerations广泛用于表示固定的一组值。

But what is the issue with normal data types? Let’s understand with help of the following example:

但是普通数据类型有什么问题? 让我们借助以下示例进行了解:

Let’s say we want to model a typical year for a calendar app. To achieve this we can simply declare and array of String type and name it months as follows:

假设我们要为日历应用程序模拟典型年份。 为此,我们可以简单地声明String类型的array ,并将其命名为months ,如下所示:

Array of months
数月

So far so good, right? Based on the knowledge of collections it is safe to assume that an array is the best choice here since we only need to identify what month of the year it is.

到目前为止一切顺利,对吗? 根据集合的知识,可以安全地假定数组是此处的最佳选择,因为我们只需要确定数组是一年中的哪个月即可。

Now let’s see what happens when we try to use this data.

现在,让我们看看尝试使用此数据时会发生什么。

Say, our calendar app tries to generate a notification if the given month is in spring season.

说,如果给定的月份是Spring,我们的日历应用会尝试生成通知。

Image for post
Table to show months and seasons
表格显示月份和季节

Let’s consider the following calendar to decide if a month is in spring or not.

让我们考虑以下日历来确定一个月是否在Spring。

If the given month is within a season as described in table then the function will return respective season, for example for January the function should return Winter.

如果给定的月份在表中所述的季节之内,则该函数将返回相应的季节,例如,对于一月,该函数应返回Winter

If an invalid month is passed in as an argument to the function then the function should return Invalid month since our table does not recognise anything other than the given twelve months. Our function will be written as follows:

如果将无效月份作为参数传递给该函数,则该函数应返回无效月份,因为我们的表无法识别给定的十二个月以外的任何内容。 我们的函数将编写如下:

Function to get respective season for a given month
获取给定月份的各个季节的功能

Notice how careful the developer has to be while calling the function. If call to the function has a typo in it, the outcome would be totally different from expectation and that makes this logic really unreliable. For example, let’s assume that the developer using above function wanted to know the result for “April” but instead of passing in “April” as a string he/she made a typo and passed in “Arpil” to the function which would result “Invalid month” as the outcome and not what he/she would have expected.

注意开发人员在调用函数时必须非常小心。 如果对函数的调用中有错字,结果将与预期完全不同,这将使此逻辑确实不可靠。 例如,假设使用上述函数的开发人员想知道“ April ”的结果,但是他/她没有输入“ April ”作为字符串,而是输入了错字,然后将“ Arpil ”传递给该函数,结果是“ 无效的月份 ”作为结果,而不是他/她所期望的结果。

Also, imagine if the logic of the function itself had a flaw in it because of a typo and instead of checking “September” in the fourth case, we were checking for “Setpember” as follows:

此外,想象一下,如果函数的逻辑本身它,因为有一个错字,而不是在第四种情况检查“ ”,我们检查“Setpember”如下的和缺陷:

Function to get respective season for a given month with typo
获取拼写错误的给定月份的季节的功能

In this scenario even if the call to the function is made with correct arguments, the function will never return expected result as shown in the following screenshot:

在这种情况下,即使使用正确的参数调用函数,该函数也永远不会返回预期结果,如以下屏幕截图所示:

Image for post
Function logic is incorrect because of the error in typing.
由于键入错误,功能逻辑不正确。

列举救援 (Enumerations to the rescue)

In the previous section we noticed that the path we took was fraught with peril.

在上一节中,我们注意到我们所走的道路充满了危险。

One thing that we learnt was that using strings as values, in cases like these, as a value to determine the next step in our process is a terrible decision and results in mistakes that are often quite hard to catch.

我们了解到的一件事是,在这样的情况下,使用字符串作为值来确定流程下一步的值是一个糟糕的决定,并导致错误常常很难发现。

So how can we solve this? and make use of Swift’s type safety to help us at compile time to make sure that we aren’t doing anything terribly wrong.

那么我们该如何解决呢? 并利用Swift的类型安全性在编译时帮助我们,以确保我们没有做任何非常错误的事情。

解决问题 (Solution to the problem)

Let’s try and solve the same problem but get rid of those strings altogether and use an enum. This time, instead of an array of months, we will create an enum named Month as follows:

让我们尝试解决相同的问题,但是完全摆脱这些字符串,并使用enum 。 这次,而不是几个月的数组,我们将创建一个名为Month的枚举,如下所示:

Enumeration for Months
数月的枚举

Inside the body of this enum, we have defined member values. Each month of the year is a different member. We can now use this datatype in the our previous function as follows:

在该枚举的主体内部,我们定义了成员值。 一年中的每个月都是不同的成员。 现在,我们可以在以前的函数中使用此数据类型,如下所示:

func season(for month: Month) -> String {}

and since the values inside enumeration are finite, when we switch over month inside the function you will notice that we don’t require the default case:

并且由于enumeration内的值是有限的,因此当我们在函数内switch month ,您会注意到我们不需要默认情况:

Function to get respective season for a given month with Enum
使用Enum获取给定月份的各个季节的函数

also, while using the member values you’ll notice something interesting. The moment you put that dot next to Month and start typing, Xcode starts auto completing for us as shown in the image below:

同样,在使用成员值时,您会注意到一些有趣的事情。 当您将点放在Month旁边并开始输入时, Xcode将为我们自动完成,如下图所示:

Image for post
Compiler auto-suggesting the option from enum member values.
编译器根据枚举成员值自动建议该选项。

There’s that compiler help we were hoping for earlier.

我们早就希望有编译器的帮助。

Because this is an actual type we defined with a set range of values, the compiler knows the different options and presents them. It makes it impossible to make a mistake.

因为这是我们定义的实际类型,具有一定范围的值,所以编译器知道不同的选项并提供它们。 这使得不可能犯错。

We simply use the type, a dot, and then it’s like we’re accessing a property. Now, let’s say I typed Setpember, like that mistake we made earlier. Well, because this is an actual value and not a string, we typed value, you’ll notice that the compiler complains that the enum case isn’t found as shown below:

我们只使用类型,点,然后就像访问属性一样。 现在,假设我输入了Setpember ,就像我们之前犯的那个错误。 好吧,因为这是一个实际值而不是字符串,所以我们键入了值,您会注意到编译器抱怨找不到枚举大小写,如下所示:

Image for post
Compiler complaining about the incorrectly typed member type
编译器抱怨成员类型输入错误

Hence with the compiler help, we’ve eliminated the possibility of typing an incorrect value.

因此,借助编译器帮助,我们消除了键入错误值的可能性。

为什么在这种情况下我们不需要默认情况? (Why don’t we need a default case in this scenario?)

The switch statement is exhaustive by nature which means that it needs to covers all possible paths for the value of the type on which we are switching the control.

switch语句本质上是详尽无遗的,这意味着它需要覆盖我们要在其上切换控件的类型的值的所有可能路径。

In the earlier scenario when we were switching on the String type a default case was required as we only covered names of the months in custom cases leaving behind a plethora of other possibilities. So, a default case was required to handle all those possibilities but in the second scenario since we were only switching on a finite set of data we did not require a default statement as all the possible cases were covered by custom cases.

在较早的场景中,当我们打开String类型时,需要一个default情况,因为我们仅在自定义情况中涵盖月份的名称,而留下了许多其他可能性。 因此,需要一个默认案例来处理所有这些可能性,但是在第二种情况下,由于我们只切换了一组有限的数据,因此我们不需要默认语句,因为所有可能的案例都已被自定义案例覆盖。

The compiler keeps a close eye on what we’re doing. For example, if we remove this Month.April case, the compiler immediately knows that all paths aren’t considered, and complains that the switch statement must be exhaustive as shown below:

编译器密切关注我们在做什么。 例如,如果删除此Month.April情况,则编译器立即知道未考虑所有路径,并抱怨switch语句必须是穷举性的,如下所示:

Image for post
Switch must be exhaustive
开关必须详尽无遗

We can either add a case for April or a default case to fix this.

我们可以添加4月的案例,也可以添加默认案例来解决此问题。

将计算的属性添加到枚举 (Adding a computed property to the Enumeration)

Another way in which we can eliminate the requirement for a separate function season is by adding a computed property to the enumeration. So we will replace the following function:

我们可以消除对单独的function季节的要求的另一种方法是通过向enumeration添加计算属性 。 因此,我们将替换以下功能:

func season(for month: Month) -> String {}

with the computed property season as shown in the code block below:

带有计算的属性season ,如下面的代码块所示:

Now, we can simply use the computed property on the enumeration as follows:

现在,我们可以简单地对枚举使用计算属性,如下所示:

Image for post
Using computed property instead of the function
使用计算属性代替函数

结论 (Conclusion)

In this article, we discussed about Enumerations in Swift. We briefly discussed how enumerations can help in solving certain programming issues and write bug free code.

在本文中,我们讨论了Swift中的 Enumerations 。 我们简要讨论了enumerations如何帮助解决某些编程问题并编写无错误代码。

In the beginning of the chapter we mentioned that Swift enums are very powerful when compared to many other languages. We will cover some of those features in upcoming articles, like the raw representable form, associated values and protocol conformance.

在本章的开头,我们提到,与许多其他语言相比, Swift枚举非常强大。 我们将在后续文章中介绍其中的一些功能,例如原始可表示形式,关联值和协议一致性。

Thanks for reading, please share it if you found it useful 🙂

感谢您的阅读,如果发现有用,请分享share

For other updates you can follow me on Twitter on my twitter handle @NavRudraSambyal.

对于其他更新,您可以在我的Twitter句柄@NavRudraSambyal的 Twitter上关注我。

翻译自: https://medium.com/swlh/swift-enumerations-71ec97584345

swift枚举

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值