泛型
泛型是 Nim 通过 type parameters “类型参数” 把过程、迭代器或类型参数化的方法。在不同的上下文里,用方括号引入类型参数,或者实例化泛型过程、迭代器及类型。
以下例子展示了如何构建一个泛型二叉树:
type
BinaryTree*[T] = ref object # 二叉树是具有
# 泛型参数 `T` 的泛型类型。
le, ri: BinaryTree[T] # 左右子树;可能是nil
data: T # 存储在节点中的数据
proc newNode*[T](data: T): BinaryTree[T] =
# 节点的构造函数
result = BinaryTree[T](le: nil, ri: nil, data: data)
proc add*[T](root: var BinaryTree[T], n: BinaryTree[T]) =
# 向树中插入一个节点
if root == nil:
root = n
else:
var it = root
while it != nil:
# 使用泛型的 `cmp` 过程,比较数据项;
# 这适用于任意具有 `==` 和 `<` 运算符的类型
var c = cmp(it.data, n.data)
if c < 0:
if it.le == nil:
it.le = n
return
it = it.le
else:
if it.ri == nil:
it.ri = n
return
it = it.ri
proc add*[T](root: var BinaryTree[T], data: T) =
# 便捷过程:
add(root, newNode(data))
iterator preorder*[T](root: BinaryTree[T]): T =
# 二叉树预遍历。
# 使用显式堆栈。
# (这比递归迭代器工厂更有效).
var stack: seq[BinaryTree[T]] = @[root]
while stack.len > 0:
var n = stack.pop()
while n != nil:
yield n.data
add(stack, n.ri) # 将右子树push到堆栈上
n = n.le # 并跟踪左子树
var
root: BinaryTree[string] # 用 `string` 实例化二叉树
add(root, newNode("hello")) # 实例化 `newNode` 和 `add`
add(root, "world") # 实例化 `add` 过程
for str in preorder(root):
stdout.writeLine(str)
这里的 T 称为 generic type parameter “泛型类型参数”,或者 type variable “类型变量”。
当前内容版权归 vectorworkshopbaoerjie 或其关联方所有,如需对内容或内容相关联开源项目进行关注与资助,请访问 vectorworkshopbaoerjie .