求值顺序
求值顺序严格从左到右,由内到外,这是大多数其他强类型编程语言的典型做法:
var s = ""
proc p(arg: int): int =
s.add $arg
result = arg
discard p(p(1) + p(2))
doAssert s == "123"
赋值也不特殊,左边的表达式在右边的表达式之前被求值:
var v = 0
proc getI(): int =
result = v
inc v
var a, b: array[0..2, int]
proc someCopy(a: var int; b: int) = a = b
a[getI()] = getI()
doAssert a == [1, 0, 0]
v = 0
someCopy(b[getI()], getI())
doAssert b == [1, 0, 0]
原由:与重载赋值或类似赋值的运算符保持一致,a = b 可以理解为 performSomeCopy(a, b) 。
然而,”求值顺序” 的概念只有在代码被规范化之后才适用。规范化涉及到模板的扩展和参数的重新排序,这些参数已经被传递给命名参数。
var s = ""
proc p(): int =
s.add "p"
result = 5
proc q(): int =
s.add "q"
result = 3
# 由于模板扩展语义,求值顺序是 'b' 在 'a' 之前。
template swapArgs(a, b): untyped =
b + a
doAssert swapArgs(p() + q(), q() - p()) == 6
doAssert s == "qppq"
# 求值顺序不受命名参数的影响:
proc construct(first, second: int) =
discard
# 'p' 在 'q' 之前求值!
construct(second = q(), first = p())
doAssert s == "qppqpq"
原由: 这比其他设想的替代方案容易实现。
当前内容版权归 vectorworkshopbaoerjie 或其关联方所有,如需对内容或内容相关联开源项目进行关注与资助,请访问 vectorworkshopbaoerjie .