元组和对象类型

元组或对象类型的变量是异构存储容器。 元组或对象定义类型的各种命名 字段 。 元组还定义了字段的 顺序 。 元组用于异构存储类型,没有开销和很少的抽象可能性。 构造函数 () 可用于构造元组。 构造函数中字段的顺序必须与元组定义的顺序相匹配。 如果它们以相同的顺序指定相同类型的相同字段,则不同的元组类型 等效 。字段的 名称 也必须相同。

元组的赋值运算符复制每个组件。 对象的默认赋值运算符复制每个组件。 在 type-bound-operations-operator 中描述了赋值运算符的重载。

  1. type
  2. Person = tuple[name: string, age: int] # 代表人的类型:人由名字和年龄组成
  3. var
  4. person: Person
  5. person = (name: "Peter", age: 30)
  6. # 一样,但不太可读:
  7. person = ("Peter", 30)

可以使用括号和尾随逗号构造具有一个未命名字段的元组:

  1. proc echoUnaryTuple(a: (int,)) =
  2. echo a[0]
  3.  
  4. echoUnaryTuple (1,)

事实上,每个元组结构都允许使用尾随逗号。

实现将字段对齐以获得最佳访问性能。 对齐与C编译器的方式兼容。

为了与 object 声明保持一致, type 部分中的元组也可以用缩进而不是 [] 来定义:

  1. type
  2. Person = tuple # 代表人的类型
  3. name: string # 人由名字
  4. age: natural # 和年龄组成

对象提供了元组不具备的许多功能。 对象提供继承和信息隐藏。 对象在运行时可以访问它们的类型,因此 of 运算符可用于确定对象的类型。 of 运算符类似于Java中的 instanceof 运算符。

  1. type
  2. Person = object of RootObj
  3. name*: string # *表示可以从其他模块访问`name`
  4. age: int # 没有*表示该字段已隐藏
  5.  
  6. Student = ref object of Person # 学生是人
  7. id: int # 有个id字段
  8.  
  9. var
  10. student: Student
  11. person: Person
  12. assert(student of Student) # is true
  13. assert(student of Person) # also true

应该从定义模块外部可见的对象字段必须用 * 标记。 与元组相反,不同的对象类型永远不会 等价 。 没有祖先的对象是隐式的 final ,因此没有隐藏的类型字段。 可以使用 inheritable pragma来引入除 system.RootObj 之外的新根对象。