Swift5-外行零基础入门_13-枚举
2020-12-25 本文已影响0人
DavidShawn
枚举
什么是枚举?
还是说回到数据类型。我们在表达某个事物的时候,可以用数字,文字进行描述;可以用流程语句来描述一段逻辑;还可以用函数,来打包某件事,用于更加方便的调用。
某些事物的性质,可以用有限的列举来表达,比如
家具的材质:木,金属,石材
汽车的品牌:比亚迪,特斯拉
为了更方便的描述事物,我们引入了枚举的概念。
枚举的形式
在下面这些例子中,我们使用了枚举:
// 列出我们经常吃的一些水果。
enum Fruit {
case apple
case banana
case orange
}
// 列出星期一到星期天
enum WeekDay {
case Monday
case Tuesday
case Wednesday
case Thursday
case Friday
case Saturday
case Sunday
}
enum
是关键词,代表要创建一个枚举;Fruit
是枚举的名称
,首字母大写;大括号
括起枚举定义
;case
关键词定义的是枚举成员值
。
这里有个概念,叫做一等类型,比如
Int
,String
等基本类型,他们可以作为参数,可以作为返回值。我们学过的函数也是一等类型,枚举enum
也是一等类型。
枚举的访问
- 访问枚举中的某个成员值
使用枚举名.成员值
的形式,可以访问到枚举中的具体成员值。
enum Fruit {
case apple
case banana
case orange
}
var a = Fruit.apple
a // apple
我们打印a
的数据类型看看。
print(type(of: a))
// Fruit
a
的数据类型是Fruit
,有点像函数,是一个自定义的数据类型。
我们还可以给a
赋值为其他的成员值。
var a = Fruit.orange
a // orange
a
的值就变成了orange
。
Swift语言提供了简写的方式赋值。
a = .banana
print(a) // banana
- 遍历枚举的成员值
既然枚举是一串数据,我们应该就可以使用for-in语句进行遍历访问,但是直接用for i in Fruit
这种语句是无法进行遍历访问的,因为Fruit
并不是一个集合值。
我们需要加一些装饰语句。首先,定义枚举的时候,要声明遵循CaseIterable
协议(协议的概念我们后面再说),然后在遍历的时候,要使用.allCases
表示枚举成员的集合。表达如下:
enum Fruit: CaseIterable {
case apple
case banana
case orange
}
for i in Fruit.allCases {
print(i)
}
// apple banana orange
枚举的应用
- 结合switch
配合switch语句,我们可以根据枚举的不同成员值,匹配出不同的动作。
var a = Fruit.apple
switch a {
case .apple:
print("我喜欢吃苹果。")
case .banana:
print("我喜欢吃香蕉。")
case .orange:
print("我喜欢吃橘子。")
}
// 我喜欢吃苹果。
这里需要注意的是,switch需要将枚举中的成员值列举完全,如果不需要列举完全,可以搭配使用default。
var a = Fruit.orange
switch a {
case .apple:
print("我喜欢吃苹果。")
case .banana:
print("我喜欢吃香蕉。")
default:
print("我喜欢吃其他水果。")
}
// 我喜欢吃其他水果。
- 关联值
枚举看起来有很多成员值,但是同一时间,枚举只能呈现一个值。
如上面的例子中,如果a
的值是苹果,switch
判断出来的执行语句就是“我喜欢吃苹果。”
利用这个特性,我们可以给枚举先定义一个框架,然后再赋值。
举例,我想选一种方式,与客户王总沟通业务,有电话沟通和邮件沟通两种方式:
enum Communication {
case phone(Int)
case email(String)
}
我先定义了一个枚举框架,这个框架中没有给任何的赋值,当我决定时,我再进行赋值:
var wangzong = Communication.phone(13888888888)
// 或者是
var wangzong = Communication.email(wangzong@163.com)
那么,如何取出这个值呢,还是用switch
:
switch wangzong {
case .phone(let phoneNumner):
print("打电话(\(phoneNumner))给王总。")
case .email(let emailAddress):
print("发邮件(\(emailAddress))给王总。")
}
这是我理解的关联值
的概念。
拓展的概念和应用
- 原始值
我们看下面这个枚举:
enum tranlate: String {
case apple = "苹果"
case banana = "香蕉"
case orange = "橘子"
}
=
后面连接的字符"苹果"
就是成员值的原始值。要注意的是,前面需要指定数据类型,后面的原始值也要遵守这个指定的数据类型。
如何访问这个原始值呢?
let word = tranlate.apple.rawValue
// 苹果
这里,我们使用了.rawValue访问到了原始值。
原始值,其实有默认值。我们继续看下面的例子:
enum tranlate: Int {
case apple
case banana
case orange
}
let word = tranlate.orange.rawValue
// 2
如果指定原始值为Int
,但是后面却没有指定,默认就是从0
开始,所以orange
的原始值是2
。
如果指定原始值为String呢?
enum tranlate: String {
case apple
case banana
case orange
}
let word = tranlate.orange.rawValue
// orange
这是,默认是原始值就是成员值本身。
- 递归
枚举的递归需要用到函数的概念。
待补充………………