Clojure多方法区分地图和地图列表
我想写一个函数,可以处理一个特定的东西(由一个映射表示)或这些映射的列表Clojure多方法区分地图和地图列表,clojure,Clojure,我想写一个函数,可以处理一个特定的东西(由一个映射表示)或这些映射的列表 是否可以为此使用defmulti/defmethod?有人能给我举一个例子,说明如何编写测试函数作为映射或映射列表吗?您可以这样做: (defmulti foo type) (defmethod foo clojure.lang.IPersistentMap [m] (println "map")) (defmethod foo clojure.lang.Sequential [m] (println "seq
是否可以为此使用defmulti/defmethod?有人能给我举一个例子,说明如何编写测试函数作为映射或映射列表吗?您可以这样做:
(defmulti foo type)
(defmethod foo clojure.lang.IPersistentMap [m]
(println "map"))
(defmethod foo clojure.lang.Sequential [m]
(println "sequential"))
但是,具有一个条件的单一功能可能会更干净,例如
(if (map? m)
(deal with the map)
(deal with each map, e.g. by recursing over each element))
Multimethods将自动使用类层次结构,因此您只需打开类型:
(defmulti process class)
(defmethod process clojure.lang.IPersistentMap [m]
(println "got map"))
(defmethod process clojure.lang.Sequential [s]
(println "got sequential"))
(defmethod process :default [o]
(println "got something else"))
在构建这样的案例时必须小心,以确保不会遇到满足两个案例的具体类型。如果是这样的话,将选择哪一个是任意的-使用preferredmethod
定义首选项。(还请注意,尽管您可以使用协议执行与上述完全相同的impl,但没有等效的方法来选择协议的首选结果)
或者,您可以让您的分派方法任意巧妙地检测您关心的案例:
(defmulti process
(fn [o]
(cond
(map? o) :map
(sequential? o) :sequential
:else (class o))))
(defmethod process :map [m]
(println "got map"))
(defmethod process :sequential [s]
(println "got sequential"))
(defmethod process :default [o]
(println "got something else"))
请注意,有多个映射类—(类{})将是PersistentArrayMap,但大多数键/值对大于8的映射实际上将是PersistentHashMaps。@您是对的。将我的示例更新为更通用。