集合类型

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

  • 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