隐式泛型
一个类型类可以直接作为参数的类型使用。
# 创建一个类型类,可以匹配所有元组和对象类型
type RecordType = (tuple or object)
proc printFields(rec: RecordType) =
for key, value in fieldPairs(rec):
echo key, " = ", value
以这种方式使用类型类的过程,被当成是 implicitly generic “隐式泛型”。 在程序中,对于每个特定参数类型组合时被实例化一次。
通常,重载解析期间,每一个被命名的类型类都将被绑定到单一的具体类型。我们称这些类型类为 bind once “单一绑定” 类型。以下是从 system 模块里直接拿来的例子:
proc `==`*(x, y: tuple): bool =
## 需要 `x` 和 `y` 都是相同的元组类型
## 针对元组的泛型运算符 `==` 建立于 `x` 和 `y` 各字段的相等性之上
result = true
for a, b in fields(x, y):
if a != b: result = false
另一种情况是用 distinct 修饰类型类,这将允许每一参数绑定到匹配类型类的不同类型。这样的类型类被称为 bind many “多绑定” 类型。
使用了隐式泛型的过程,常常需要引用匹配的泛型类型内的类型参数。使用 . 语法能便捷地实现此功能:
type Matrix[T, Rows, Columns] = object
...
proc `[]`(m: Matrix, row, col: int): Matrix.T =
m.data[col * high(Matrix.Columns) + row]
下面是关于隐式泛型更多的例子:
proc p(t: Table; k: Table.Key): Table.Value
# 大致等同于:
proc p[Key, Value](t: Table[Key, Value]; k: Key): Value
proc p(a: Table, b: Table)
# 大致等同于:
proc p[Key, Value](a, b: Table[Key, Value])
proc p(a: Table, b: distinct Table)
# 大致等同于:
proc p[Key, Value, KeyB, ValueB](a: Table[Key, Value], b: Table[KeyB, ValueB])
typedesc 作为参数类型使用时,也会产生隐式泛型,typedesc 有其独有的规则:
proc p(a: typedesc)
# 等同于以下写法:
proc p[T](a: typedesc[T])
typedesc 是一个 “多绑定” 类型类:
proc p(a, b: typedesc)
# 大致等同于:
proc p[T, T2](a: typedesc[T], b: typedesc[T2])
typedesc 类型的参数本身可以作为一个类型使用。如果其作为类型使用,就是底层类型。换言来说,”typedesc” 剥离了一层。
proc p(a: typedesc; b: a) = discard
# 大致等同于:
proc p[T](a: typedesc[T]; b: T) = discard
# 所以这是合法的:
p(int, 4)
# 这里参数 'a' 需要的是一个类型, 而 'b' 需要的则是一个值。
当前内容版权归 vectorworkshopbaoerjie 或其关联方所有,如需对内容或内容相关联开源项目进行关注与资助,请访问 vectorworkshopbaoerjie .