泛型
泛型是Nim用 类型化参数 参数化过程,迭代器或类型的方法。它们对于高效型安全容器很有用:
- type
- BinaryTree*[T] = ref object # 二叉树是左右子树用泛型参数 ``T`` 可能nil的泛型
- le, ri: BinaryTree[T]
- data: T # 数据存储在节点
- proc newNode*[T](data: T): BinaryTree[T] =
- # 节点构造
- new(result)
- result.data = data
- proc add*[T](root: var BinaryTree[T], n: BinaryTree[T]) =
- # 插入节点
- if root == nil:
- root = n
- else:
- var it = root
- while it != nil:
- # 比较数据; 使用对任何有 ``==`` and ``<`` 操作符的类型有用的泛型 ``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)
该示例显示了通用二叉树。根据上下文,括号用于引入类型参数或实例化通用过程、迭代器或类型。如示例所示,泛型使用重载:使用“add”的最佳匹配。 序列的内置 add 过程没有隐藏,而是在 preorder 迭代器中使用。