枚举是为一组相关的值定义了一个共同的类型,使得在代码中以类型安全的方式来使用。
一、枚举语法
- 枚举简单使用:
// 写法1
enum Direction1 {
// 使用case定义一个枚举成员值
case Left // 成员值(或成员)
case Right
case Top
case Bottom
}
// 写法2
enum Direction2 {
case Left, Right, Top, Bottom
}
var directionToHead1 = Direction1.Left;
// directionToHead1类型已经被系统推断为Direction1类型,即可以使用点语法进行设置
directionToHead1 = .Right;
与C和Objective-C不同,Swfit中的枚举成员在创建时不会被赋予一个默认的整形值。例如,在上面
Direction1
,Left
,Right
,Top
,Bottom
是不会被隐式赋值0
,1
,2
,3
。即是这些枚举成员本身就是完备的值,这些值的类型是已经明确定义好的Direction1
类型。
二、使用switch匹配枚举值
- 判断一个枚举类型的值时,
switch
语句必须穷举所有情况,如果忽略一种情况那么程序将编译不通过,即需要考虑枚举中的全部成员。这也是强制穷举:
enum Direction2 {
case Left, Right, Top, Bottom;
}
var directionToHead2 = Direction2.Right;
switch directionToHead2 {
// 必须考虑Direction2中的每一种情况
case .Left:
print("向左");
case .Right:
print("向右");
case .Top:
print("向上");
case .Bottom:
print("向下");
}
- 实际使用时,是不需要匹配每个枚举成员的,即可以提供
default
分支来涵盖所有未明确处理的枚举成员:
switch directionToHead2 {
case .Left:
print("向左");
default: // 涵盖其他枚举成员的处理
print("不需要处理");
}
三、关联值
关联值即是给枚举成员设置一个常量或变量,这不但可以在赋值后可以查看,也可以在代码中使用枚举成员时修改这个关联值:
可以用枚举类存储任意类型的关联值,如果需要,每个枚举成员的关联值类型都可以不同。枚举特性和C语言中的联合体相似:
/**
ip地址,现在有IPv4和IPv6
*/
enum IpAddress {
// IPv4格式为: xxx.xxx.xxx.xxx
case IPv4(Int,Int,Int,Int);
// IPv6格式为: xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx
case IPv6(Int,Int,Int,Int,Int,Int,Int,Int);
}
// 存储本机ip地址,这是IPv4形式
var myIpAddress = IpAddress.IPv4(192, 168, 0, 1);
// 也可以将本机ip地址写成IPv6形式
// 备注: 不要在意这种转换是否正确
myIpAddress = .IPv6(0, 0, 0, 0, 192, 168, 0, 1);
注意:
myIpAddress
原本是IpAddress.IPv4(192, 168, 0, 1)
,之后
被IPv6(0, 0, 0, 0, 192, 168, 0, 1)
所替代。即是IpAddress
类型的常量和变量只能存储一个. IPv4
或一个. IPv6
,但只能存储这两个值中的其中一个!!!
关联值的提取使用:
// 输出ip地址,只有将关联值提取出来
switch myIpAddress {
// 提取出为常量或变量
case .IPv4(let num1, let num2, let num3, let num4):
print("ip地址:\(num1):\(num2):\(num3):\(num4)");
// 更为简便的写法,即将`var`或`let`标注在成员名前面
case let .IPv6(num1, num2, num3, num4, num5, num6, num7, num8):
print("ip地址:\(num1):\(num2):\(num3):\(num4):\(num5):\(num6):\(num7):\(num8)");
}
四、原始值
- 关联值替代选择,枚举成员可以被默认值(称为原始值)预填充,原始值的类型必须相同:
// 设置原始值,定义的时候要指定类型
enum Number:Int{
case Zero = 0;
case One = 1;
case Two = 2;
}
注意: 原始值和关联值是不同的。原始值是在定义枚举时被预先填充的值。对于特定的枚举成员,它的原始值始终不变的。关联值是创建一个基于枚举成员的常量或变量时才设置的值,枚举成员的关联值可以改变的。
- 原始值的隐式赋值,即在不需要显式为每一个枚举成员设置原始值,swift将会自动赋值:
enum Number:Int {
case Zero = 0, One, Two, Three, Four, Five, Six, Seven, Eight, Nine;
// Number.Zero原始值是0,那么Number.One原始值就为1,以此类推.
}