泛型
泛型是nim参数化过程的手段,迭代器或者类型有类型参数。他们对于有效类型安全容器是非常有用的:
type
BinaryTreeObj[T] = object # BinaryTree is a generic type with BinaryTree是一个泛型有泛型参数T
# with generic param ``T``
le, ri: BinaryTree[T] # left and right subtrees; may be nil 左右子树,可能是nil
data: T # the data stored in a node data存放在一个节点中
BinaryTree*[T] = ref BinaryTreeObj[T] # type that is exported
proc newNode*[T](data: T): BinaryTree[T] =
# constructor for a node 构造一个节点
new(result)
result.data = data
proc add*[T](root: var BinaryTree[T], n: BinaryTree[T]) =
# insert a node into the tree 向树种插入一个节点
if root == nil:
root = n
else:
var it = root
while it != nil:
# compare the data items; uses the generic ``cmp`` proc 比较data项,使用通用的`cmp``过程,它作用于任何类型,有"=="和"<"操作符
# that works for any type that has a ``==`` and ``<`` operator
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) =
# convenience proc:
add(root, newNode(data))
iterator preorder*[T](root: BinaryTree[T]): T =
# Preorder traversal of a binary tree.
# Since recursive iterators are not yet implemented,
# this uses an explicit stack (which is more efficient anyway):
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 right subtree onto the stack
n = n.le # and follow the left pointer
var
root: BinaryTree[string] # instantiate a BinaryTree with ``string``
add(root, newNode("hello")) # instantiates ``newNode`` and ``add``
add(root, "world") # instantiates the second ``add`` proc
for str in preorder(root):
stdout.writeln(str)
上面的例子展示了一个通用的二叉树。根据上下文,括号是用来介绍类型参数或者实例化一个通用过程,迭代器,或类型。如例子所示,泛型伴随重载:最合适的add方法被使用。内置的序列的add方法不是隐藏的,它被应用在perorder迭代器中。