如何在 clojure 中设置和获取多方法元数据?
How to set and get multimethod metadata in clojure?
我正在使用多种方法来解析命令行命令及其参数。
(defmulti run (fn [command args] command))
(defmethod run :default
[& _]
...)
^{:args "[command]"}
(defmethod run "help"
[_ & [args]]
"Display command list or help for a given command"
...)
^{:args ""}
(defmethod run "version"
[_ & [args]]
"Print program's version"
...)
(defn -main
[& args]
(run (first args)
(next args)))
当我尝试访问元数据时,对于特定方法,clojure returns nil
:
(meta ((methods run) "help"))
没有这种可能。第一个原因(直截了当的原因)是 defmethod
不提供为特定方法设置元数据的能力(只有 defmulti
允许这样做,但仅限于整个多方法)。第二个原因是 multimethod 本质上是一个函数,只是有多个 "variants" 执行,每个执行都取决于传递的参数。粗略地说,从调用者的角度来看,下面定义的函数 f1
和 f2
之间没有特别的区别:
(defmulti f1 (fn [x] x))
(defmethod f1 :foo [x]
...)
(defmethod f1 :bar [x]
...)
(defmethod f1 :baz [x]
...)
(defn f2 [x]
(case x
:foo ...
:bar ...
:baz ...))
就我个人而言,我会根据实现细节来考虑特定函数是多方法还是普通函数。此外,如果您需要显式记录 multimehod 的每个方法,则应考虑将每个方法替换为普通函数,并且根本不要使用 multimethods。
我正在使用多种方法来解析命令行命令及其参数。
(defmulti run (fn [command args] command))
(defmethod run :default
[& _]
...)
^{:args "[command]"}
(defmethod run "help"
[_ & [args]]
"Display command list or help for a given command"
...)
^{:args ""}
(defmethod run "version"
[_ & [args]]
"Print program's version"
...)
(defn -main
[& args]
(run (first args)
(next args)))
当我尝试访问元数据时,对于特定方法,clojure returns nil
:
(meta ((methods run) "help"))
没有这种可能。第一个原因(直截了当的原因)是 defmethod
不提供为特定方法设置元数据的能力(只有 defmulti
允许这样做,但仅限于整个多方法)。第二个原因是 multimethod 本质上是一个函数,只是有多个 "variants" 执行,每个执行都取决于传递的参数。粗略地说,从调用者的角度来看,下面定义的函数 f1
和 f2
之间没有特别的区别:
(defmulti f1 (fn [x] x))
(defmethod f1 :foo [x]
...)
(defmethod f1 :bar [x]
...)
(defmethod f1 :baz [x]
...)
(defn f2 [x]
(case x
:foo ...
:bar ...
:baz ...))
就我个人而言,我会根据实现细节来考虑特定函数是多方法还是普通函数。此外,如果您需要显式记录 multimehod 的每个方法,则应考虑将每个方法替换为普通函数,并且根本不要使用 multimethods。