• 集合类型
    • 位字段

    集合类型

    集合模拟了数学集合的概念。 集合的基类型只能是固定大小的序数类型,它们是:

    • int8-int16
    • uint8/byte-uint16
    • char
    • enum或等价类型。对有符号整数集合的基类型被定义为在 0 .. MaxSetElements-1 的范围内, 其中 MaxSetElements 目前是2^16。

    原因是集合被实现为高性能位向量。尝试声明具有更大类型的集将导致错误:

    1. var s: set[int64] # 错误: 集合太大

    集合可以通过集合构造器来构造: {} 是空集合。 空集合与其它具体的集合类型兼容。构造器也可以用来包含元素(和元素范围):

    1. type
    2. CharSet = set[char]
    3. var
    4. x: CharSet
    5. x = {'a'..'z', '0'..'9'} # 构造一个包含'a'到'z'和'0'到'9'的集合

    集合支持的操作符:

    操作符含义
    A + B并集
    A * B交集
    A - B差集
    A == B相等
    A <= B子集
    A < B真子集
    e in A元素
    e notin AA不包含元素e
    contains(A, e)包含元素e
    card(A)A的基 (集合A中的元素数量)
    incl(A, elem)A = A + {elem}
    excl(A, elem)A = A - {elem}

    位字段

    集合经常用来定义过程的 标示 。这比定义必须或在一起的整数常量清晰并且类型安全。

    枚举、集合和强转可以一起用:

    1. type
    2. MyFlag* {.size: sizeof(cint).} = enum
    3. A
    4. B
    5. C
    6. D
    7. MyFlags = set[MyFlag]
    8.  
    9. proc toNum(f: MyFlags): int = cast[cint](f)
    10. proc toFlags(v: int): MyFlags = cast[MyFlags](v)
    11.  
    12. assert toNum({}) == 0
    13. assert toNum({A}) == 1
    14. assert toNum({D}) == 8
    15. assert toNum({A, C}) == 5
    16. assert toFlags(0) == {}
    17. assert toFlags(7) == {A, B, C}

    注意集合如何把枚举变成2的指数。

    如果和C一起使用枚举和集合,使用distinct cint。

    为了和C互通见 bitsize pragma 。