如何在 macro/template 中获取函数名称作为字符串?

How to get function name as string in macro/template?

无法弄清楚如何在宏中获取函数名称作为字符串。

下面的代码应该生成 rlisten("multiply", multiply) 但它不会编译,playground

import macros

proc rlisten*[A, B, R](fn: string, op: proc(a: A, b: B): R): void =
  echo fn

macro remotefn(fn): void =
  quote do:
    rlisten($`fn`, `fn`) # It should generte `rlisten("multiply", multiply)`

proc multiply(a, b: int): int = discard
remotefn multiply

首先您需要接受 typeduntyped 参数给宏。在这种特殊情况下,您需要使用 typed 参数才能访问函数 symbol(符号是被编译器的类型解析传递替换的标识符)。

import macros

proc rlisten*[A, B, R](fn: string, op: proc(a: A, b: B): R): void =
  echo fn

macro remotefn(fn: typed): void =
  echo fn.treeRepr()
  # ^ Show tree representation of the argument. In this particular case it is just a
  # single function symbol.
  let name = fn.strVal()
  echo "Function name is ", name

proc multiply(a, b: int): int = discard
remotefn multiply

产出

Sym "multiply"
Function name is multiply