标签追踪
异常追踪是 effect system “Effect 系统”的一部分。抛出异常是一个 effect 。当然可以定义其他 effect 。自定义 effect 是一种给例程打 标签 并做检查的方法:
type IO = object ## 输入/输出 effect
proc readLine(): string {.tags: [IO].} = discard
proc no_effects_please() {.tags: [].} =
# 编译器禁止这么做:
let x = readLine()
标签必须是类型名称。同 raises 列表一样,tags 列表也可以附加到过程类型上。这会影响类型的兼容性。
标签追踪的推断规则与异常追踪的推断规则类型类似。
有一种禁止某些 effect 出现的方法:
type IO = object ## input/output effect
proc readLine(): string {.tags: [IO].} = discard
proc echoLine(): void = discard
proc no_IO_please() {.forbids: [IO].} =
# 这是可以的,因为它没有定义任何标签:
echoLine()
# 编译器会阻止这种情况:
let y = readLine()
forbids 编译指示定义了一个被禁止的 effect 的列表 —— 如果任何语句具有这些 effect,则编译会失败。 带有 effect 禁止列表的过程类型是不带这种列表的过程类型的子类型:
type MyEffect = object
type ProcType1 = proc (i: int): void {.forbids: [MyEffect].}
type ProcType2 = proc (i: int): void
proc caller1(p: ProcType1): void = p(1)
proc caller2(p: ProcType2): void = p(1)
proc effectful(i: int): void {.tags: [MyEffect].} = echo $i
proc effectless(i: int): void {.forbids: [MyEffect].} = echo $i
proc toBeCalled1(i: int): void = effectful(i)
proc toBeCalled2(i: int): void = effectless(i)
## 这将会失败,因为toBeCalled1使用了ProcType1所禁止的MyEffect:
caller1(toBeCalled1)
## 这是可以的,因为toBeCalled2和ProcType1有相同的限制:
caller1(toBeCalled2)
## 这些都是可以的,因为ProcType2没有副作用限制:
caller2(toBeCalled1)
caller2(toBeCalled2)
ProcType2 是 ProcType1 的子类型。与 tags 编译指示所不同的是,父上下文将:调用具有禁用副作用的其他函数的函数;不继承禁用副作用列表。
当前内容版权归 vectorworkshopbaoerjie 或其关联方所有,如需对内容或内容相关联开源项目进行关注与资助,请访问 vectorworkshopbaoerjie .