一、前言

  • 枚举是为一组相关值定义的一个通用类型,Swift 枚举的功能非常强大,使它比 OC 的枚举应用于更广泛的场景。
  • 在本文,我们去了解 enum 的语法和能力。

二、枚举语法

  • 使用 enum 关键字引入枚举,其整个定义放在一对大括号内:
enum CompassPoint {case northcase southcase eastcase west
}
  • 与 C 和 Objective-C 不同,Swift 的枚举成员在创建时不会被赋予一个默认的整型值。

三、枚举成员遍历

  • 令枚举遵循 CaseIterable 协议,Swift 会生成一个 allCases 属性,用于返回枚举中所有成员的集合。
enum Beverage: CaseIterable {case coffee, tea, juice
}for beverage in Beverage.allCases {print(beverage)
}// coffee
// tea
// juice
关联值
  • 关联值是将附加信息附加到枚举成员的一种非常好的方式。Swift 枚举可以存储任意类型的关联值,例子如下:
enum Barcode {case upc(Int, Int, Int, Int)case qrCode(String)
}
  • 上面的代码定义一个名为 Barcode 的枚举类型,其中一个成员 upc 具有(Int, Int, Int, Int) 类型的关联值,另一个成员 qrCode 具有 String 类型的关联值。可以通过模式匹配来访问关联值,例子如下:
var productBarcode = .qrCode("ABCDEFGHIJKLMNOP")
switch productBarcode {case let .upc(numberSystem, manufacturer, product, check):print("UPC: \(numberSystem), \(manufacturer), \(product), \(check).")
case let .qrCode(productCode):print("QR code: \(productCode).")
}
// 打印“QR code: ABCDEFGHIJKLMNOP.”

四、原始值

  • 枚举成员可以被默认值预填充,这些默认值被称为原始值,注意:原始值的类型必须相同。
enum ASCIIControlCharacter: Character {case tab = "\t"case lineFeed = "\n"case carriageReturn = "\r"
}
  • 默认情况下,Swift 只支持下面4种类型的枚举值:整型、浮点数、字符串、布尔值。如果要支持更多类型的枚举值,需要实现指定的协议,这个在后面的文章中会讲到。

五、原始值的隐式赋值

  • 在使用的原始值是整数或字符串类型时,Swift 可以为你自动赋值。
  • 当使用的原始值是整数时,隐式赋值的值会一次增加1。如果第一个枚举成员没有设置原始值,其默认原始值是 0。
enum Planet: Int {case mercury = 1, venus, earth, mars, jupiter, saturn, uranus, neptune
}
// Plant.mercury 的显式原始值为 1,Planet.venus 的隐式原始值为 2,依此类推。
  • 当使用字符串作为枚举成员的原始值时,每个枚举成员的隐式原始值是该成员的名字。
enum CompassPoint: String {case north, south, east, west
}// CompassPoint.south 拥有隐式原始值 south,依此类推。
  • 可以使用 rawValue 属性访问枚举成员的原始值:
let earthsOrder = Planet.earth.rawValue
// earthsOrder 值为 3let sunsetDirection = CompassPoint.west.rawValue
// sunsetDirection 值为 "west"

六、使用原始值初始化枚举实例

  • 如果在定义枚举时使用了原始值,那么会自动生成一个初始化方法,这个方法有一个 rawValue 参数,参数类型即为原始值类型:
let possiblePlanet = Planet(rawValue: 7)
// possiblePlanet 类型为 Planet? 值为 Planet.uranus
  • 原始值构造器是一个可失败的构造器,因为并不是每一个原始值都有一个与之对应的枚举成员,因此其返回类型是可选类型。

七、递归枚举

  • 递归枚举是一种枚举类型,它的一个或多个成员使用该枚举类型作为关联值。在枚举成员前加上 indirect 关键字表示该成员可递归:
enum ArithmeticExpression {case number(Int)indirect case addition(ArithmeticExpression, ArithmeticExpression)indirect case multiplication(ArithmeticExpression, ArithmeticExpression)
}
也可以在枚举类型开头加上 indirect 来表明其所有成员都可递归:indirect enum ArithmeticExpression {case number(Int)case addition(ArithmeticExpression, ArithmeticExpression)case multiplication(ArithmeticExpression, ArithmeticExpression)
}
  • 其使用如下:
let five = ArithmeticExpression.number(5)
let four = ArithmeticExpression.number(4)
let sum = ArithmeticExpression.addition(five, four)
let product = ArithmeticExpression.multiplication(sum, ArithmeticExpression.number(2))func evaluate(_ expression: ArithmeticExpression) -> Int {switch expression {case let .number(value):return valuecase let .addition(left, right):return evaluate(left) + evaluate(right)case let .multiplication(left, right):return evaluate(left) * evaluate(right) // (5 + 4) * 2}
}print(evaluate(product))// 打印“18”

八、嵌套枚举

  • Swift 中允许枚举嵌套,在使用时,需要确保一个枚举类型是从属于另一个枚举类型的,否则会引起语义混乱。下面看一个例子:
enum Character {enum Weapon {case Bowcase Swordcase Lancecase Dagger}enum Helmet {case Woodencase Ironcase Diamond}case Thiefcase Warriorcase Knight
}// 通过层级来访问嵌套的枚举成员
let character = Character.Thief
let weapon = Character.Weapon.Bow
let helmet = Character.Helmet.Iron
  • 访问嵌套枚举成员时,不必每次都输入这么长的层级来访问,可以使用便捷方法直接访问,如下:
func strength(of character: Character, with weapon: Character.Weapon, and armor: Character.Helmet) {}strength(of: .thief, with: .bow, and: .wooden)

九、包含枚举

  • 也可以在结构或类中嵌入枚举。继续前面的例子:
struct Character {enum CharacterType {case thiefcase warriorcase knight}enum Weapon {case bowcase swordcase lancecase dagger}let type: CharacterTypelet weapon: Weapon
}let warrior = Character(type: .warrior, weapon: .sword)

十、方法和属性

  • Swift 枚举类型可以附加方法和属性:
enum Transportation {case car(Int)case train(Int)func distance() -> String {switch self {case .car(let miles): return "\(miles) miles by car"case .train(let miles): return "\(miles) miles by train"}}
}
  • 与结构或类类型的主要区别在于,可以在方法中使用 self 来计算输出。

十一、“属性”添加限制

  • Swift 中不允许添加存储属性,下面的代码会编译报错:
enum Device {case iPadcase iPhonelet introduced: Int // Enums must not contain stored properties
}
  • 应该使用计算属性,如下:
enum Device {case iPad,case iPhonevar introduced: Int {switch self {case .iPhone: return 2007case .iPad: return 2010}}
}

十二、静态方法

  • 静态方法是可以通过类型名称而不是类型的特定实例调用的方法。例子如下:
enum Device {static var newestDevice: Device {return .appleWatch}case iPad,case iPhonecase appleWatch
}

十三、可变方法

  • 通过 mutating 关键字将方法声明为可变方法,在可变方法中可以修改 self 实例,例子如下:
enum TriStateSwitch {case off, low, brightmutating func next() {switch self {case .off:self = lowcase .low:self = .brightcase high:self = off}}
}var ovenLight = TriStateSwitch.lowovenLight.next()
// ovenLight is now equal to .brightovenLight.next()
// ovenLight is now equal to .off

Swift之枚举enum的语法和功能相关推荐

  1. Swift 中枚举、结构体、类(enum、struct、class)

    Swift 中枚举.结构体.类(enum.struct.class) Swift中的枚举与OC相比不会自动分配初始值,值的类型不会限定为整数,可以给定关联值类型和具体值(整型.浮点型.字符型(Swif ...

  2. Swift之深入解析枚举enum的底层原理

    一.Swift 枚举 枚举简单的说也是一种数据类型,只不过是这种数据类型只包含自定义的特定数据,它是一组有共同特性的数据的集合. Swift 的枚举类似于 Objective C 和 C 的结构,枚举 ...

  3. iOS开发-Swift进阶之枚举enum!

    swift进阶总汇 本文主要介绍enum的常见使用形式,以及枚举大小是如何计算的 补充:添加脚本自动生成SIL 通过target -> +,选择 other -> Aggregate,然后 ...

  4. swift_017(Swift 的枚举)

    //***********swift学习之17--枚举--*************************** // 枚举简单的说也是一种数据类型,只不过是这种数据类型只包含自定义的特定数据,它是一 ...

  5. swift学习二:基本的语法

    声明本文转载自:http://www.cocoachina.com/applenews/devnews/2014/0603/8653.html Swift是什么? Swift是苹果于WWDC 2014 ...

  6. c++ enum 给定类型_C++11作用域内枚举enum

    在C++11之前的枚举(enum),是没有办法两个枚举(enum)内有相同枚举名的.如果还不知道C++中枚举(enum)是什么,可以看这篇:枚举enum 如:苹果和桔子都有大,中,小.写个代码来说明下 ...

  7. 在JavaScript中定义枚举的首选语法是什么? [关闭]

    在JavaScript中定义枚举的首选语法是什么? 就像是: my.namespace.ColorEnum = {RED : 0,GREEN : 1,BLUE : 2 }// later onif(c ...

  8. Java枚举(enum)常用的用法总结

    Java枚举[enum] Java枚举(enum)七种常见的用法汇总如下: 用法一:常量 用法二:switch 用法三:向枚举中添加新方法 用法四:覆盖枚举的方法 用法五:实现接口 用法六:使用接口组 ...

  9. 枚举(enum)类型

    关键字enum 可以将一组具名的值的有限集合创建一种新的类型,而这些具名的值可以作为常规的程序使用.创建enum 时,编译器会为你生成一个相关的类,这个类继承自java.lang.Enum .下面是一 ...

最新文章

  1. 《擦屁股先生》词:你挚爱的强哥
  2. B - Dungeon Master POJ - 2251
  3. 2019春季暑期实习生正式批招聘笔试【腾讯】(回忆版)第二题
  4. 笔记-中项案例题-2018年上-人力资源管理
  5. Linux常用命令--uname
  6. linux消息队列优缺点,linux消息队列概念
  7. 中国公有云厂商2017年收入利润综合排名
  8. 计算机指令load是什么意思,overload
  9. python股票策略_用Python编程彼得林奇PEG价值选股策略
  10. 在个人计算机系统中 常见外存储器有(),内蒙古事业单位专业知识计算机考试题库:计算机基础练习题(22)...
  11. css+div实现导航栏
  12. 【katacontainer基础知识】kata-container介绍与原理
  13. Schlumberger New Energy、CEA与合作伙伴宣布,欧洲委员会批准成立清洁氢气生产技术企业Genvia
  14. 云队友丨任正非:没有退路,就是胜利之路
  15. 第一章 日常生活中的正念
  16. 电脑磁盘占用100%解决办法
  17. codevs 4052 黎恒健大战YJY
  18. 麦克米伦高阶词典三星7500单词
  19. 第一篇,网络管理--网络特工
  20. 支付宝账单的背后,大数据时代“芳华”隐现

热门文章

  1. 计算机与在勘察地质中的应用,计算机在石油地质中的应用探究
  2. 单片机数据区传送程序设计
  3. 高度自律是怎样一种人生体验(二)
  4. Harbor的部署和使用
  5. SOA Psummarize SOAP概述
  6. 牛顿迭代法之雅可比迭代的matlab仿真
  7. 用 leangoo进行自我账目管理
  8. 用计算机弹的九八k简谱,作曲 编曲 配器 录音 混音 母带 MIDI 电脑音乐制作(超级全能宝典)...
  9. nova4e升级鸿蒙,看完这三点 告诉你华为nova4e为什么值得买
  10. GPU中的SM和warp的关系