元组和对象类型
元组或对象类型的变量是异构存储容器。 元组或对象定义类型的各种命名 字段 。 元组还定义了字段的 顺序 。 元组用于异构存储类型,没有开销和很少的抽象可能性。 构造函数 () 可用于构造元组。 构造函数中字段的顺序必须与元组定义的顺序相匹配。 如果它们以相同的顺序指定相同类型的相同字段,则不同的元组类型 等效 。字段的 名称 也必须相同。
元组的赋值运算符会对每个组件进行复制。 对象的默认赋值运算符也会复制每一个组件。 在 这里 描述了赋值运算符的重载。
- type
- Person = tuple[name: string, age: int] # 代表人的类型:人由名字和年龄组成
- var
- person: Person
- person = (name: "Peter", age: 30)
- # 一样,但不太可读:
- person = ("Peter", 30)
可以使用括号和尾随逗号构造具有一个未命名字段的元组:
- proc echoUnaryTuple(a: (int,)) =
- echo a[0]
- echoUnaryTuple (1,)
事实上,每个元组结构都允许使用尾随逗号。
实现将字段对齐以获得最佳访问性能。 对齐与C编译器的方式兼容。
为了与 object 声明保持一致, type 部分中的元组也可以用缩进而不是 [] 来定义:
- type
- Person = tuple # 代表人的类型
- name: string # 人由名字
- age: natural # 和年龄组成
对象提供了元组不具备的许多功能。 对象提供继承和信息隐藏。 对象在运行时可以访问它们的类型,因此 of 运算符可用于确定对象的类型。 of 运算符类似于Java中的 instanceof 运算符。
- type
- Person = object of RootObj
- name*: string # *表示可以从其他模块访问`name`
- age: int # 没有*表示该字段已隐藏
- Student = ref object of Person # 学生是人
- id: int # 有个id字段
- var
- student: Student
- person: Person
- assert(student of Student) # is true
- assert(student of Person) # also true
应该从定义模块外部可见的对象字段必须用 * 标记。 与元组相反,不同的对象类型永远不会 等价 。 没有祖先的对象是隐式的 final ,因此没有隐藏的类型字段。 可以使用 inheritable pragma来引入除 system.RootObj 之外的新根对象。