过程
大多数编程语言称之为 方法 或 函数 在Nim中称为 过程 。 过程声明由标识符,零个或多个形式参数,返回值类型和代码块组成。
正式参数声明为由逗号或分号分隔的标识符列表。 形参由 : 类型名称 给出一个类型。
该类型适用于紧接其之前的所有参数,直到达到参数列表的开头,分号分隔符或已经键入的参数。
分号可用于使类型和后续标识符的分隔更加清晰。
- # 只使用逗号
- 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 is optional with 47 as its default value
- proc foo(a: int, b: int = 47): int
参数可以声明为可变的,因此允许proc通过使用类型修饰符 var 来修改这些参数。
- # 通过第二个参数 ``返回`` 一个值给调用者
- # 请注意,该函数根本不使用实际返回值(即void)
- proc foo(inp: int, outp: var int) =
- outp = inp + 47
如果proc声明没有正文,则它是一个 前向 声明。 如果proc返回一个值,那么过程体可以访问一个名为 result 的隐式声明的变量。
过程可能会重载。 重载解析算法确定哪个proc是参数的最佳匹配。
示例:
- proc toLower(c: char): char = # toLower for characters
- 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]) # calls toLower for characters; no recursion!
调用过程可以通过多种方式完成:
- proc callme(x, y: int, s: string = "", c: char, b: bool = false) = ...
- # call with positional arguments # parameter bindings:
- callme(0, 1, "abc", '\t', true) # (x=0, y=1, s="abc", c='\t', b=true)
- # call with named and positional arguments:
- callme(y=1, x=0, "abd", '\t') # (x=0, y=1, s="abd", c='\t', b=false)
- # call with named arguments (order is not relevant):
- callme(c='\t', y=1, x=0) # (x=0, y=1, s="", c='\t', b=false)
- # call as a command statement: no () needed:
- callme 0, 1, "abc", '\t' # (x=0, y=1, s="abc", c='\t', b=false)
过程可以递归地调用自身。
运算符 是具有特殊运算符符号作为标识符的过程:
- proc `$` (x: int): string =
- # 将整数转换为字符串;这是一个前缀运算符。
- result = intToStr(x)
具有一个参数的运算符是前缀运算符,具有两个参数的运算符是中缀运算符。 (但是,解析器将这些与运算符在表达式中的位置区分开来。) 没有办法声明后缀运算符:所有后缀运算符都是内置的,并由语法显式处理。
任何运算符都可以像普通的proc一样用 'opr' 表示法调用。(因此运算符可以有两个以上的参数):
- proc `*+` (a, b, c: int): int =
- # Multiply and add
- result = a * b + c
- assert `*+`(3, 4, 6) == `+`(`*`(a, b), c)