• 过程类型

    过程类型

    过程类型在内部是指向过程的指针。 nil 是过程类型变量的允许值。 Nim使用过程类型来实现 函数式 编程技术。

    Examples:

    1. proc printItem(x: int) = ...
    2.  
    3. proc forEach(c: proc (x: int) {.cdecl.}) =
    4. ...
    5.  
    6. forEach(printItem) # 无法编译,因为调用约定不同
    1. type
    2. OnMouseMove = proc (x, y: int) {.closure.}
    3.  
    4. proc onMouseMove(mouseX, mouseY: int) =
    5. # 有默认的调用约定
    6. echo "x: ", mouseX, " y: ", mouseY
    7.  
    8. proc setOnMouseMove(mouseMoveEvent: OnMouseMove) = discard
    9.  
    10. # 可以, 'onMouseMove'有默认的调用约定,它是兼容的
    11. # 到 'closure':
    12. setOnMouseMove(onMouseMove)

    过程类型的一个微妙问题是过程的调用约定会影响类型兼容性:过程类型只有在具有相同的调用约定时才是兼容的。 作为一个特殊的扩展,调用约定 nimcall 的过程可以传递给一个参数,该参数需要调用约定 closure 的proc。

    Nim支持这些 调用约定:

    nimcall 是用于Nim proc 的默认约定。它与 fastcall 相同,但仅适用于支持 fastcall 的C编译器。

    • closure
    • 是缺少任何pragma注释的 过程类型 的默认调用约定。 它表示该过程具有隐藏的隐式形参(环境)。 具有调用约定 closure 的过程变量占用两个机器字:一个用于proc指针,另一个用于指向隐式传递环境的指针。
    • stdcall
    • 这是微软指定的stdcall约定。生成的C过程使用 __stdcall 关键字声明。
    • cdecl
    • cdecl约定意味着过程应使用与C编译器相同的约定。 在Windows下,生成的C过程使用 __cdecl 关键字声明。
    • safecall
    • 这是微软指定的safecall约定。 生成的C过程使用 _safecall 关键字声明。 安全_ 一词指的是所有硬件寄存器都应被推送到硬件堆栈。
    • inline
    • 内联约定意味着调用者不应该调用该过程,而是直接内联其代码。 请注意,Nim不是内联的,而是将其留给C编译器;它生成 __inline 程序。 这只是编译器的一个提示:编译器可能完全忽略它,它可能内联没有标记为 inline 的过程。
    • fastcall
    • Fastcall对不同的C编译器意味着不同的东西,不论C的 __fastcall 意义是什么。
    • syscall
    • 系统调用约定与C中的 __syscall 相同,用于中断。
    • noconv
    • 生成的C代码将没有任何显式调用约定,因此使用C编译器的默认调用约定。 这是必需的,因为Nim对程序的默认调用约定是 fastcall 来提高速度。大多数调用约定仅适用于Windows 32位平台。

    默认调用约定是 nimcall ,除非它是内部proc(proc中的proc)。 对于内部过程,无论是否访问其环境,都会执行分析。 如果它这样做,它有调用约定 closure ,否则它有调用约定 nimcall