30-枚举
enum
类型提供了通过列举一个类型的所有可能取值来定义此类型的方式,比如:
- 星期一到星期日可以是一种枚举
- 不同的颜色的组成可以是一种枚举
- 观看的电影列表可以是一种枚举
enum 的定义
定义 enum
时需要把它所有可能的取值一一列出,我们称这些值为 enum
的构造器(或者 constructor
)。
javascript
enum RGBColor {
| Red | Green | Blue
}
enum 是定义枚举的关键字, RGBColor 是这种枚举的名称, Red 、Green 、 Blue 是枚举中可选的值。他们以 | 作为分割,其中 Red前面的**|** 是可选的
javascript
enum RGBColor {
Red | Green | Blue
}
enum的构造器
enum
中的构造器还可以携带若干(至少一个)参数,称为有参构造器。比如enum
中的构造器还可以携带若干(至少一个)参
数,称为有参构造器
javascript
enum RGBColor {
| Red(UInt8) | Green(UInt8) | Blue(UInt8)
}
enum
支持递归定义
javascript
enum Expr {
| Num(Int64)
| Add(Expr, Expr)
| Sub(Expr, Expr)
}
main() {
let a = Expr.Add(Expr.Num(23), Expr.Num(Int64(42)))
}
enum
定义成员函数、操作符函数
但是要求构造器、成员函数、成员属性之间不能重名
javascript
enum RGBColor {
| Red | Green | Blue
public static func printType() {
print("RGBColor")
}
}
enum 的使用
定义了 enum
类型之后,就可以创建此类型的实例(即 enum
值),enum
值只能取 enum
类型定义中的一个构造器。enum
没有构造函数,可以通过 类型名.构造器
,或者直接使用构造器的方式来构造一个 enum
值(对于有参构造器,需要传实参)
javascript
enum RGBColor {
| Red | Green | Blue(UInt8)
}
main() {
let r = RGBColor.Red
let g = Green
let b = Blue(100)
}
当省略类型名时,enum
构造器的名字可能和类型名、变量名、函数名发生冲突。此时必须加上 enum
类型名来使用 enum
构造
器,否则只会选择同名的类型、变量、函数定义。
下面的例子中,只有构造器 Blue(UInt8)
可以不带类型名使用,Red
和 Green(UInt8)
皆会因为名字冲突而不能直接使用,
必须加上类型名 RGBColor
。
javascript
let Red = 1
func Green(g: UInt8) {
return g
}
enum RGBColor {
| Red | Green(UInt8) | Blue(UInt8)
}
let r1 = Red // Will choose 'let Red'
let r2 = RGBColor.Red // Ok: constructed by enum type name
let g1 = Green(100) // Will choose 'func Green'
let g2 = RGBColor.Green(100) // Ok: constructed by enum type name
let b = Blue(100) // Ok: can be uniquely identified as an enum constructor
如下的例子中,只有构造器 Blue
会因为名称冲突而不能直接使用,必须加上类型名 RGBColor
。
javascript
class Blue {}
enum RGBColor {
| Red | Green(UInt8) | Blue(UInt8)
}
let r = Red // Ok: constructed by enum type name
let g = Green(100) // Ok: constructed by enum type name
let b = Blue(100) // Will choose constructor of 'class Blue' and report an error