Skip to content

30-枚举

enum 类型提供了通过列举一个类型的所有可能取值来定义此类型的方式,比如:

  1. 星期一到星期日可以是一种枚举
  2. 不同的颜色的组成可以是一种枚举
  3. 观看的电影列表可以是一种枚举

enum 的定义

定义 enum 时需要把它所有可能的取值一一列出,我们称这些值为 enum 的构造器(或者 constructor)。

javascript
enum RGBColor {
    | Red | Green | Blue
}

enum 是定义枚举的关键字, RGBColor 是这种枚举的名称, RedGreenBlue 是枚举中可选的值。他们以 | 作为分割,其中 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) 可以不带类型名使用,RedGreen(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

Released under the MIT License.