clojure中的记录文档

Geo*_*mms 12 documentation record clojure

我以前有一个api,其中有许多功能,所有这些都需要一个非常特殊的格式的地图.当它来记录这个API,我发现,在这些功能的每我被重复的文档字符串"与此函数被调用的地图上必须是如此这般的格式,并且在地图上的该字段表示如此这般".

所以我认为这些函数更好地记录,而我可以只记录记录.然而,似乎不可能记录记录,至少以doc宏或Marginalia 解释的方式记录.

这里建议的解决方案是"只需在记录的元数据中添加一个:doc键".

我试过(defrecord ^{:doc "Here is some documentation"} MyRecord [field1 field2])但宏观扩展这表明它没有任何影响.还defrecord返回一个java.lang.class没有实现IMeta 的实例,所以我不确定我们能给它元数据吗?

  • 如何记录记录?
  • 记录是否适用于此处?

fer*_*hur 9

TL; DR:不幸的是你不能.

来自文档:

符号和集合支持元数据

当你使用时,defrecord你实际上正在创建一个java类.由于类既不是符号也不是Clojure记录,因此您无法向它们附加文档.

更详细的说明

以下REPL会话显示了无法将元数据附加到记录的原因.

user=> (defrecord A [a b])
#<Class@61f53f0e user.A>
user=> (meta A)  ;; <= A contains no metadata
nil  
Run Code Online (Sandbox Code Playgroud)

这里要注意的重要一点是A是一个普通的java类.如果您尝试为A设置元数据,您将收到一个有趣的错误

user=> (with-meta A {:doc "Hello"}) 

ClassCastException java.lang.Class cannot be cast to clojure.lang.IObj
Run Code Online (Sandbox Code Playgroud)

显然与meta期望a clojure.lang.IObj.既然java.lang.Class是一个Java-land构造,它显然一无所知clojure.lang.IObj.

我们来看看源代码吧 with-meta

user=> (source with-meta)
(def
 ^{:arglists '([^clojure.lang.IObj obj m])
   :doc "Returns an object of the same type and value as obj, with
    map m as its metadata."
   :added "1.0"
   :static true}
 with-meta (fn ^:static with-meta [^clojure.lang.IObj x m]
             (. x (withMeta m))))
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,此方法希望x有一个withMeta对象,该对象显然没有.