Var 返回类型
过程、转换器或者迭代器可以返回 var 类型,表示返回的是一个左值,调用者可以修改它:
var g = 0
proc writeAccessToG(): var int =
result = g
writeAccessToG() = 6
assert g == 6
如果隐式创建的指向某地址的指针,有可能在其生命周期之外继续访问它,那么编译器会报告静态错误:
proc writeAccessToG(): var int =
var g = 0
result = g # 错误!
当迭代器返回元组时,元组的元素也可以是 var 类型:
iterator mpairs(a: var seq[string]): tuple[key: int, val: var string] =
for i in 0..a.high:
yield (i, a[i])
在标准库中,所有返回 var 类型的例程,都遵循以 m 为前缀的命名规范。
通过 var T 返回的内存是安全的,这由简单的借用规则来保证: 如果 result 未指向堆的地址(即在 result = X 中, X 涉及到 ptr 或 ref 访问),那么它必须来自例程的第一个参数。
proc forward[T](x: var T): var T =
result = x # 可以, 来自第一个参数。
proc p(param: var int): var int =
var x: int
# 我们知道 'forward' 提供了一个从其第一个参数 'x' 得出的地址的视图
result = forward(x) # 错误: 地址来自 `x` ,
# 其不是p的第一个参数,
# 并且存活在栈上。
换句话说, result 所指向的生命周期与第一个参数的生命周期相关联,这就足以验证调用位置的内存安全。
未来的方向
新版本的 Nim 借用规则将更加准确,比如使用这样的语法:
proc foo(other: Y; container: var X): var T from container
这里的 var T from contaner 显式指定了返回值的地址必须源自第二个参数(本例的 ‘container’)。 var T from p 语句指明了类型 varTy[T, 2] 与 varTy[T, 1] 类型不兼容。
当前内容版权归 vectorworkshopbaoerjie 或其关联方所有,如需对内容或内容相关联开源项目进行关注与资助,请访问 vectorworkshopbaoerjie .