过程
大多数编程语言中称之为 methods:idx “方法”或 functions:idx “函数”,在 Nim 中则称为 procedures:idx “过程”。 过程声明由标识符、零个或多个形参、返回值类型和代码块组成,形参声明为由逗号或分号分隔的标识符列表。形参由 : typename 给出一个类型。 该类型适用于紧接其之前的所有参数,直到参数列表的开头的分号分隔符或已经键入的参数。 分号可使类型和后续标识符的分隔更加清晰。
# 只使用逗号
proc foo(a, b: int, c, d: bool): int
# 使用分号进行显式的区分
proc foo(a, b: int; c, d: bool): int
# 会失败: a是无类型的, 因为 ';' 为停止类型传播
proc foo(a; b: int; c, d: bool): int
可以使用默认值声明参数,如果调用者没有为参数提供值,则使用该默认值,每次调用函数时,都会重新计算该值。
# b是可选的, 默认值为 47 。
proc foo(a: int, b: int = 47): int
参数可以声明为可变的,过程允许通过类型修饰符 var 来修饰参数。
# 通过第二个参数 "返回" 一个值给调用者
# 请注意, 该函数实际没有使用真实的返回值(即 void)
proc foo(inp: int, outp: var int) =
outp = inp + 47
如果 proc 声明没有过程体, 则是 forward “前置”声明。 如果 proc 返回一个值,那么过程体可以访问一个名为 result 的隐式变量。 过程可能会重载,重载解析算法会确定哪个 proc 是参数的最佳匹配。 示例:
proc toLower(c: char): char = # toLower 字符
if c in {'A'..'Z'}:
result = chr(ord(c) + (ord('a') - ord('A')))
else:
result = c
proc toLower(s: string): string = # 字符串 toLower
result = newString(len(s))
for i in 0..len(s) - 1:
result[i] = toLower(s[i]) # 为字符调用 toLower ,不递归!
调用过程可以通过多种方式完成:
proc callme(x, y: int, s: string = "", c: char, b: bool = false) = ...
# 带位置参数的调用 # 参数绑定:
callme(0, 1, "abc", '\t', true) # (x=0, y=1, s="abc", c='\t', b=true)
# 使用命名参数和位置参数调用:
callme(y=1, x=0, "abd", '\t') # (x=0, y=1, s="abd", c='\t', b=false)
# 带命名参数的调用(顺序无关):
callme(c='\t', y=1, x=0) # (x=0, y=1, s="", c='\t', b=false)
# 作为命令语句调用:不需要():
callme 0, 1, "abc", '\t' # (x=0, y=1, s="abc", c='\t', b=false)
过程可以递归地调用自身。
Operators “操作符”是将特定运算符作为标识符的过程:
proc `$` (x: int): string =
# 将整数转换为字符串;这是一个前缀操作符。
result = intToStr(x)
具有一个参数的操作符是前缀操作符,有两个参数的运算符是中缀操作符。(但是, 解析器将这些与操作符在表达式中的位置区分开来。) 无法声明后缀运算符,所有后缀运算符都是内置的,由语法明确指出。
任何操作符都可以像普通的 proc 一样用 `opr` 表示法调用。(因此操作符可以有两个以上的参数):
proc `*+` (a, b, c: int): int =
# 乘 和 加
result = a * b + c
assert `*+`(3, 4, 6) == `+`(`*`(a, b), c)
当前内容版权归 vectorworkshopbaoerjie 或其关联方所有,如需对内容或内容相关联开源项目进行关注与资助,请访问 vectorworkshopbaoerjie .