枚举为一组相关值定义了一个通用类型,从而可以让你在代码中类型安全地操作这些值。
特性
- Swift 中的枚举可以是字符串、字符、任意的整数值,或者是浮点类型。
- Swift 中的枚举成员可以指定任意类型的值来与不同的成员值关联储存(合集)。
- Swift 中的枚举是具有自己权限的一类类型(计算属性、实例方法、扩展等)。
枚举语法
/// 定义枚举
enum Direction {
case top
case left
case bottom
case right
}
/// 使用 Switch 语句来匹配枚举值
let direction = Direction.top
switch direction {
case .top:
// TODO
default:
break
}
// 不能给未指定类型的枚举成员提供值(case top = "Top"❌)
error: Enum case cannot have a raw value if the enum does not have a raw type
// 并且无法使用rawValue属性(direction.rawValue❌)
error: Value of type 'Direction' has no member 'rawValue'
- Swift 中的枚举可以不指定类型,如果不指定类型则不能设置成员值、且不能使用rawValue属性
原始值
// MARK: -隐式原始值
/// 时分秒
enum Time: Float {
case second
case minute
case hour
}
/// 年月日
enum DateTime: String {
case day
case month
case year
}
// MARK: -显式原始值
/// 形状 (提供原始值)
enum Shape: String {
case circle = "Circle"
case square = "Square"
case prismatic = "Prismatic"
case oval = "Oval"
}
// MARK: -隐式+显式原始值
/// 行星 (只提供第一个成员的原始值)
enum Planet: Int {
case mercury = 1
case venus
case earth
}
// 当数值被用于作为原始值时,每个成员的隐式值都比前一个大一。如果第一个成员没有值,那么它的值是 0 。
let time = Time.second
print(time. rawValue) // 0.0
// 当字符串被用于原始值,那么每一个成员的隐式原始值则是那个成员的名称。
let date = DateTime.year
print(date. rawValue) // "year"
// 显示原始值
let shape = Shape.square
print(shape. rawValue) // "Square"
// Planet.mercury有一个明确的原始值 1,后续的每成员的隐式值都比前一个大一
let planet = Planet. venus
print(planet. rawValue) // 2
- 枚举类型可以是字符串、字符、任意的整数值,或者是浮点类型。
- 如果没有给指定类型的枚举成员提供原始值,那么Swift 将会自动为枚举成员分配值(即:隐式指定的原始值)。可以通过rawValue属性来访问一个枚举成员的原始值。
原始值初始化
let shape = Shape(rawValue: "ball")
print(type(of: shape)) // Optional<Shape>
- 原始值的初始化器总是返回可选的枚举成员,不能直接使用 Switch 语句来匹配枚举值
计算属性、实例方法、Extension
extension Shape {
/// 不能增加存储属性
// var size: CGSize? ❌
// error: Enums must not contain stored properties
/// 可以添加计算属性
var description: String {
switch self {
case .circle:
return "圆"
case .square:
return "矩形"
case .prismatic:
return "棱形"
case .oval:
return "椭圆"
}
}
/// 实例方法
func currentShape() -> String {
return self.rawValue
}
/// 静态方法
static func objectShape() {
}
}
- swift枚举的计算属性用来提供关于枚举当前值的额外信息,并且实例方法用来提供与枚举表示的值相关的功能。
关联值
enum Shopping {
case clothes(number: Int, discount: Float)
case shoes(size: String, price: Float)
}
// 协议抽离计算属性
protocol DescriptionConvertible {
var description: String { get }
}
extension Shopping: DescriptionConvertible {
var description: String {
switch self {
case .clothes(let number, let price):
return "衣服\(number)件,\(price)折"
case .shoes(let size, let price):
return "鞋子\(size)码,单价\(price)RMB"
}
}
}
let clothes = Shopping.clothes(number: 2, discount: 8)
print(clothes.description) // 衣服2件,8折
- Swift 枚举可以存储任意给定类型的关联值,将其它类型的关联值与这些成员值一起存储
number/discount/size/price是任意给定的类型,并且这些关联值会与clothes/shoes成员值一起存储。并且这些关联值可以在switch匹配中使用
合集
enum Apprearance {
enum Sizes {
static let gutter: CGFloat = 15
static let cardGutter: CGFloat = 8
}
enum Color {
static let primaryColor = UIColor(red: 0.22, green: 0.58, blue: 0.29, alpha: 1.0)
static let secondaryColor = UIColor.lightGray
static let background = UIColor.white
enum Red {
static let medium = UIColor(red: 0.22, green: 0.58, blue: 0.29, alpha: 1.0)
}
}
}
// 使用
self.view.backgroundColor = Apprearance.Color.Red.medium
- swift枚举可以定义一组相关成员的合集作为枚举的一部分,每一个成员都可以有不同类型的值的合集与其关联。
- 可以多级嵌套,使用于最小化常量作用域(Constants)
遍历枚举
enum Direction: CaseIterable {
case top
case left
case right
case bottom
}
for item in Direction.allCases {
print(item)
}
- swift枚举是可以遍历的,但前提是要求遵守CaseIterable协议,就可以通过allCases获取所有的枚举成员。
相关资料:
Swift编程语言-枚举
最小化常量作用域
网友评论