April 3, 2023
By: Kevin
Clojure docstring
最近在写一个Clojure代码统计工具的时候, 需要把docstring计算为注释的一部分, 做了个更深入的了解.
第一个问题就是, 哪些结构可以有docstring?
ns, def, defn, defprotocol, defmacro, defmulti都可以使用docstring.
defrecord, deftype, defmethod反而不能用, 是不是有点意外?
本质上的原因是docstring是var(clojure.lang.Var)这个类型的metadata.
如果定义的类型是直接的Java类型, 而不是var, 则不能使用docstring
分别举几个🌰
ns
命名空间(namespace)应该有自己的docstring.
(ns device-sensor.socket.tcp
"TCP通讯, 可以扩展支持其他tcp协议.
主要功能为tcp连接, tcp的包到具体协议帧的组装, 帧组装完整后的处理(放到对应的stream)
对外提供服务的有如下函数:
1. `parse-x-packages`: 处理xa package, 参数为xa协议的tcp client
2. `parse-x-packages`: 处理x package, 参数为a协议的tcp client
3. `parse-f-packages`: 处理 FSMD加速卡package, 参数为FSMD协议的tcp client"
{:author "lizy", :last-update-date "2022-02-28"}
(:require
[taoensso.timbre :as timbre :refer [debug error log spy]]))
defn, defmacro, defn-
对于docstring来说写法是一样的.
(defn raw-client
"以`host`和`port` 为参数, 返回一个defered aleph客户端"
[host port]
(tcp/client {:host host, :port port}))
如果是multi-arity(不同参数个数的重载)的情况, 只能有一个docstring
(defn my-func
"这是 my-func 的文档字符串。支持以下重载:
- (my-func x) 做了某些事情
- (my-func x y) 做了另一些事情
- (my-func x y z) 做了不同的事情"
([x] (...))
([x y] (...))
([x y z] (...)))
def
名字之后, 定义之前
(def a-bf "doc string for a-buf" (atom nil))
defprotocol
需要protocol的函数定义中写明docstring
(defprotocol MainTask
"定义了主任务的所有操作接口, 需要实现以下函数"
(immediate? "如果立即执行返回true, 否则false"
[this])
(gen-sub-tasks "生成子任务"
[this order])
(run-task! "立即执行的任务直接执行,不走schedule机制"
[this order])
(schedule-task! "用于执行主任务的调度, 关联定时器, 定时器触发给设备下发指令"
[this order])
(cancel-schedule! "取消任务"
[this])
(change-state "任务状态修改"
[this order]))
defmulti
docstring只能加在defmulti中, defmethod不行呀, 只能老老实实去写注释.
(defmulti msg-handler
"根据不同的编码分别进行处理"
:sub-cmd-result-func-code)
(defmethod msg-handler :func-code1
;; 只能在这里写注释了, 不能有docstring
...)
(defmethod msg-handler :func-code2
;; 只能在这里写注释了, 不能有docstring
...)
mount.core/defstate
mount.core中, defstate支持docstring.
(defstate schedulers
"对应多个`operation`的多任务系统, 这个atom用于存储多个context的状态"
:start (atom {})
:stop (when (seq @schedulers)
(debugf "调度器结束 %s" (str (keys @schedulers)))))
(clojure.repl/doc schedulers)
;; -------------------------
;; clj-scheduler.schedulers/schedulers
;; 对应多个`operation`的多任务系统, 这个atom用于存储多个context的状态