macros - 如何使用 `clojure.tools.macro/name-with-attributes` ?

标签 macros clojure

我发现对于任何在 clojure.tools.macro 中编写类似 defn 的宏的人来说,这将是一个很棒的工具。图书馆:name-with-attributes功能。文档字符串说:

To be used in macro definitions. Handles optional docstrings and attribute maps for a name to be defined in a list of macro arguments. If the first macro argument is a string, it is added as a docstring to name and removed from the macro argument list. If afterwards the first macro argument is a map, its entries are added to the name's metadata map and the map is removed from the macro argument list. The return value is a vector containing the name with its extended metadata map and the list of unprocessed macro arguments.

但我似乎找不到在任何地方使用此函数的示例。

那么,我如何使用这个函数来定义一个 defn2 宏,它应该是包含所有相同内容的 clojure.core/defn 的克隆功能,包括:

  • 文档字符串
  • 属性映射
  • 先决条件
  • 多方面

最佳答案

这是defn2:

(require '[clojure.tools.macro :as ctm])

(defmacro defn2
  "A clone of `defn`."
  [symb & defn-args]
  (let [[symb body] (ctm/name-with-attributes symb defn-args)]
    `(defn ~symb ~@body)))

查看元数据,我们可以看到它已正确附加:

(defn2 ^:private add
       "Docstring"
       ([] :foo)
       ([a b] {:pre [(= 1 1)]} (+ a b)))

(pprint (meta #'add))

...产量:

{:arglists ([] [a b]),
 :ns #<Namespace user>,
 :name add,
 :column 1,
 :private true,
 :doc "Docstring",
 :line 1,
 :file
 "/private/var/folders/30/v73zyld1359d7jb2xtlc_kjm0000gn/T/form-init8938188655190399857.clj"}

使用上面的 defn2 创建了一个 add 函数,其工作方式如下:

(add)     ; => :foo
(add 1 2) ; => 3

关于macros - 如何使用 `clojure.tools.macro/name-with-attributes` ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25478158/

相关文章:

clojure - Clojure 中读取字符串和加载字符串的区别

Clojure 编译时常量

vba - 如果文件 = "False"Application.GetOpenFileName 错误 13 类型不匹配

inheritance - 可扩展的宏定义

rust - 将程序宏代码编译或将值堆栈到可执行文件中?

java - Clojure 自定义 Java 互操作

variables - MASM - 宏变量?

macros - 如何在 Rust 宏中匹配 "mut"?

Clojure 规范 "conformer"函数,它是什么?

Clojure/Incanter 数据转换功能