我之前有一个api,其中包含许多功能,所有功能都需要一个非常特殊的格式的地图。在记录这个API时,我发现在每个函数的文档字符串中我都在重复“调用此函数的映射必须是这样的格式,并且映射的这个字段意味着这样的等等。“
所以我认为这些函数记录更好,而且我可以只记录记录。但是,似乎不可能记录记录,至少以doc
宏或Marginalia解释的任何方式记录。
建议here的解决方案是“只需在记录的元数据中添加一个:doc键”。
我试过了(defrecord ^{:doc "Here is some documentation"} MyRecord [field1 field2])
但宏扩展这表明它没有任何效果。另外defrecord
会返回java.lang.class
的实例,但不会实现IMeta,所以我不确定是否可以为其提供元数据?
答案 0 :(得分:8)
TL; DR:很遗憾你不能。
来自https://www.sitepoint.com/a-step-by-step-guide-to-building-an-android-audio-player-app/:
符号和集合支持元数据
使用user=> (defrecord A [a b])
#<Class@61f53f0e user.A>
user=> (meta A) ;; <= A contains no metadata
nil
时,实际上是在创建一个java类。由于类既不是符号也不是Clojure记录,因此不能向它们附加文档。
更详细的解释
以下REPL会话显示了无法将元数据附加到记录的原因。
user=> (with-meta A {:doc "Hello"})
ClassCastException java.lang.Class cannot be cast to clojure.lang.IObj
这里要注意的重要一点是A是一个普通的java类。 如果您尝试为A设置元数据,您将收到一个有趣的错误
clojure.lang.IObj
显然with-meta期望java.lang.Class
。由于clojure.lang.IObj
是一个Java-land构造,因此它显然不知道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))))
x
正如您所看到的,此方法希望withMeta
具有#s2 .back
对象,该记录显然没有。
答案 1 :(得分:0)
您不能在记录中添加文档字符串。但是,如果您真的想要,那么就可以有效。
如果希望阅读代码的用户知道您的意图,则可以在代码中添加注释。
如果您希望创建记录实例的用户可以通过工具访问您的文档字符串,则可以修改创建的构造函数的元数据。例如:
(let [docstring "The string-representation *MUST* be ISO8601."
arglists '([string-representation millis-since-epoch])
arglists-map '([{:keys [:string-representation :millis-since-epoch]}])]
(defrecord Timestamp [string-representation millis-since-epoch])
(alter-meta! #'->Timestamp assoc :doc docstring)
(alter-meta! #'->Timestamp assoc :arglists arglists)
(alter-meta! #'map->Timestamp assoc :doc docstring)
(alter-meta! #'map->Timestamp assoc :arglists arglists-map))
对于在草书中使用REPL的我来说,当我询问“参数信息”时,我会看到argslist弹出窗口,而当我询问“快速文档”时,会看到文档字符串。
或者,更好的方法可能是为您自己的构造函数提供标准文档字符串。