类型类
类型类是特殊的伪类型,可在重载解析或使用 is 运算符时针对性地匹配某些类型。Nim 支持以下内置类型类:
类型 | 匹配 |
---|---|
object | 任意 object 类型 |
tuple | 任意 tuple 类型 |
enum | 任意 enumeration |
proc | 任意 proc 类型 |
iterator | 任意 iterator 类型 |
ref | 任意 ref 类型 |
ptr | 任意 ptr 类型 |
var | 任意 var 类型 |
distinct | 任意 distinct 类型 |
array | 任意 array 类型 |
set | 任意 set 类型 |
seq | 任意 seq 类型 |
auto | 任意 类型 |
此外,任何泛型类型都会自动创建一个同名的类型类,可匹配该泛型类的任意实例。
类型类通过标准的布尔运算符可组合成更复杂的类型类。
# 创建一个类型类,可以匹配所有元组和对象类型
type RecordType = (tuple or object)
proc printFields[T: RecordType](rec: T) =
for key, value in fieldPairs(rec):
echo key, " = ", value
泛型参数列表中的参数类型约束可以通过 , 进行分组,并以 ; 结束,就像宏和模板中的参数列表那样:
proc fn1[T; U, V: SomeFloat]() = discard # T 没有类型约束
template fn2(t; u, v: SomeFloat) = discard # t 没有类型约束
虽然类型类在语法上接近于类 ML 语言中的代数数据类型 (ADT),但应该知道,类型类只是实例化时所必须遵守的静态约束。 类型类本身并非真的类型,只是一种检查系统,检查泛型是否最终被 解析 成某种单一类型。 与对象、变量和方法不同,类型类不允许运行时的类型动态特性。
例如,以下代码无法通过编译:
type TypeClass = int | string
var foo: TypeClass = 2 # foo 的类型在这里被解释为 int 类型
foo = "this will fail" # 这里发生错误,因为 foo 是 int
Nim 允许将类型类和常规类型用作泛型类型参数的 type constraints “类型约束”:
proc onlyIntOrString[T: int|string](x, y: T) = discard
onlyIntOrString(450, 616) # 可以
onlyIntOrString(5.0, 0.0) # 类型不匹配
onlyIntOrString("xy", 50) # 不行,因为同一个 T 不能同时是两种不同的类型
proc 和 iterator 类型类也接受一个调用约定指示,以限制匹配的 proc 或 iterator 类型的调用约定。
proc onlyClosure[T: proc {.closure.}](x: T) = discard
onlyClosure(proc() = echo "hello") # valid
proc foo() {.nimcall.} = discard
onlyClosure(foo) # type mismatch
当前内容版权归 vectorworkshopbaoerjie 或其关联方所有,如需对内容或内容相关联开源项目进行关注与资助,请访问 vectorworkshopbaoerjie .