Swift教程(八)--枚举

本次的教程是基于Swift5.1版本

枚举定义语法

首先,我们来看看在 swift 中定义枚举的语法:

enum CompassPoint {
case north
case south
case east
case west
}

我们注意到,swift 的每个枚举项前面,都使用一个 case 关键字来标识。除了每行声明一个枚举项,也可以将这些枚举项放在一行中声明,每项之间用逗号分隔:

enum CompassPoint {
case north,south, east, west
}

注意一点,Objective-C 和 C 语言那样, swift 中的枚举项不可以用 0,1,2 这样的数字值来代替。它们有自己的值。

枚举类型定义好之后,我们就可以将它的枚举值赋值给某个变量:

var myNorth  = CompassPoint.north

并且,对于类型明确的变量,我们可以直接省去枚举的类型前缀:

var mySouth:CompassPoint = .south

枚举的使用

枚举值可以在 switch 语句中进行匹配:

switch myNorth {
case .north:
print("north")
case .south:
print("south")
case .east:
print("east")
case .west:
print("west")
}

在 switch 语句中的每个 case 中,我们提供各个枚举项的名称:.Monday,.Tuesday 等等。在 swift 中 switch 中匹配枚举项,必须显示的列举出所有的枚举项。也就是对于我们上面表示星期的枚举类型WeekDay, 我们对它的 switch 语句中必须将所有的枚举项分支都明确的写出来。否则就会有编译错误。

这个机制也体现了 Swift 类型安全的核心思想。如果我们觉得每个枚举项都要明确的指定行为比较麻烦,我们还可以使用 default 分支来对于其余的枚举项定义行为:

switch myNorth {
case .north:
print("north")
case .south:
print("south")
case .east:
print("east")
default:
print("west")
}

总之,无论用 default 也好,还是明确对每一个枚举项指定行为也好,在 Swift 中,我们都必须对枚举类型下的每个值,指定确定的行为。不能漏掉其中任何一个可能性。

关联值(Associated Values)

在 Swift 中,我们还可以定义这样的枚举类型,它的每一个枚举项都有一个附加信息,来扩充这个枚举项的信息表示,这又叫做关联值。加入我们有一个枚举类型Shape 来表示形状。

这个形状可以是矩形,也可以是圆形,等等。而每种具体的形状又对应了不同的属性,比如矩形有长,宽,圆形有,圆心,半径,等等。那么枚举的关联值就可以帮我们解决这个问题:

enum Shape {
case Rectangle(CGRect)
case Circle(CGPoint,Int)

}

我们看到,每个枚举项的后面,都包含了一对括号,这里面定义了这个枚举项的关联值的类型。对于 Rectangle 我们使用一个 CGRect 来表示他的原点和长宽属性。 而对于 Circle,我们使用一个包含了 CGPoint 和 Int 类型的元组(Tuple) 来表示这个圆的圆心和半径。

这样我们在初始化枚举类型的时候,我们就可以根据每个枚举项的关联值类型,为它指定附加信息了:

var rect = Shape.Rectangle(CGRect(x: 1, y: 1, width: 100, height: 100))

var circle = Shape.Circle(CGPoint(x: 1, y: 1), 2)

我们再看一下,带有关联值的枚举项在 switch 语句中的用法:

switch rect {
case .Rectangle(let rect):
print(rect)
case let .Circle(center,radius):
print(center,radius)
}
//输出:(1.0, 1.0, 100.0, 100.0)

我们在 case 后面用一对括号来输出枚举项的关联值,可以用 let 或者 var 关键字,分别作为常量和变量进行输出。我们这里这样来使用case .Rectangle(let rect)。对于关联值是包含多个值的元组类型的,我们可以将 let 关键字放置在枚举项类型的前面,这样就可以不用对每个关联值都声明let 关键字了,let .Circle(center, radius)。

原始值(Raw Values)

我们刚刚了解了关联值类型的枚举的使用,Swift 的枚举类型还提供了另外一个叫做原始值(Raw Values)的实现。和关联值不同,它为枚举项提供一个默认值,这个默认值是在编译的时候就确定的。而不像关联值那样,要再实例化枚举值的时候才能确定。

这也就是说,原始值对于同一个枚举项都是一样的。而关联值对于同一个枚举项只是值的类型相同,但具体的取值也是不同的。

下面我们来看一下定义枚举原始值 (Raw Values) 的方法:

enum WeekDayWithRaw : String {
case Monday = "1. Monday"
case Tuesday = "2. Tuesday"
case Wednesday = "3. Wednesday"
case Thursday = "4. Thursday"
case Friday = "5. Friday"
case Saturday = "6. Saturday"
case Sunday = "7. Sunday"

}

还是表示星期的枚举类型,我们对每个枚举项都定义了一个默认的原始值,注意一下我们定义枚举的第一行代码,enum WeekDayWithRaw : String 我们在枚举定义的最后,多加了一个String 关键字,这就表示这个枚举的原始值(Raw Values) 是 String 类型的。

定义好了原始值后,我们就可以用枚举项的 rawValue 属性来输出它:

print(WeekDayWithRaw.Saturday.rawValue)
//输出:6. Saturday

我们还可以通过原始值(Raw Values) 来初始化枚举类型:

let day = WeekDayWithRaw(rawValue: "3. Wednesday")

这个初始化方法的返回值是一个 Optionals。所以我们可以用 Optionals 的组合链来使用它的返回值:

if let day = WeekDayWithRaw(rawValue: "3. Wednesday") {
print(day)
}else{
print("error")
}

//输出:Wednesday

返回值为 Optionals 的类型,代表这个方法可以返回一个具体的值,也可以返回 nil, 因为我们传入初始化方法的原始值,可能会不等于我们预设的那几个值。

本文分享自微信公众号 - iOS开发笔记(roclel)

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-07-11

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏歪脖贰点零

我对"大前端"的偏见

写这篇也是忐忐忑忑,一个后端聊前端的话题,总显得那么不专业,见识所限,仅供参考。此文的来由也是由前篇文章引申出来的,详见前端工程化的个人思考+前端工程化的个人思...

10420
来自专栏漏洞战争

推荐今年C3黑客大会上的几个议题

最近几天在德国举办的 The 35th Chaos Communication Congress (35C3) 黑客大会,在Twitter上传得火热,在国内却无...

14610
来自专栏镁客网

苹果供应链消息:明年的iPhone会装有ToF相机

手机厂商一向热衷于在相机上做出创新尝试,苹果也不例外。就在最近,根据供应链的消息,苹果正要求供应商为明年的iPhone手机准备ToF相机镜头组件。

11220
来自专栏友弟技术工作室

(效率人生)MAC必备工具Alfred进阶之Workflow

使用Alfred的Powerpack和工作流,您可以扩展Alfred并以自己的方式完成任务。用工作流程代替重复性的任务,提高你的工作效率。 workflow工...

67420
来自专栏ionic3+

【技巧】ionic3修改自定义图标

我们需要把它裁切并转成svg格式再生成字体图标,比较繁琐,而我新系统目前也没有装相应软件,所以这里不采用这些图标,选用网上已有类似的字体图标来代替。

13930
来自专栏01二进制

千秋万代,一统江湖——Flutter for All Screens

2018年2月27日,Google发布了Flutter的第一个Beta版本,由于自己是一个Google粉,所以很快就下载尝鲜了,之后还在简书上发过一篇博客《你好...

11640
来自专栏iOSDevLog

iOS VLC Swift 版 : 使用 cocoapods 集成 MobileVLCKit-3.3.2

https://www.videolan.org/vlc/download-ios.html

21020
来自专栏我只不过是出来写写iOS

Xcode10.2 继承UITableView协议失效

 前言:在这次App版本迭代进入集成测试阶段尾声,正式环境打包release环境后,测试回归发现许多包含 tableView 的页面都无法响应点击事件。但是在 ...

15060
来自专栏01二进制

利用flutter_downloader插件在Flutter中实现文件下载

之前有做一个工具集的微信小程序「开挂Lite」,但是由于小程序自身限制,没有办法实现下载文件的功能,只能把下载链接解析出来。而且受限于微信平台,小程序的审核是一...

1.4K30
来自专栏WebJ2EE

React:Table 那些事(2)—— 解读 W3C 规范

—— https://www.w3.org/TR/CSS22/sample.html

20530

扫码关注云+社区

领取腾讯云代金券

年度创作总结 领取年终奖励