Clojure Multimethods区分地图和地图列表

int*_*tar 1 clojure

我想编写一个可以处理特定事物(由地图表示)或这些地图列表的函数.

是否可以使用defmulti/defmethod?有人能指出我如何编写测试函数作为地图或地图列表的例子吗?

Ale*_*ler 5

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"))
Run Code Online (Sandbox Code Playgroud)

你必须小心建立这样的案例,以确保你没有遇到满足两种情况的具体类型.如果是这样,那将是任意选择 - 用于prefer-method定义偏好.(另请注意,虽然您可以使用协议执行与上述完全相同的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"))
Run Code Online (Sandbox Code Playgroud)