Living Without Multimethods
假设需要写一个print函数,用于打印各种类型。你可能会这么写
(defn my-print [ob]
(cond
(nil? ob) (.write *out* "nil")
(string? ob) (.write *out* ob)))
每次要支持新的类型就在cond下面添加,这种方式不好。
定义多重方法
;如下定义一个多重方法,name是方法名,dispatch-fn是一个调度函数。
(defmulti name dispatch-fn)
;如果是以参数类型区分,就像my-print。那么可以将dispatch-fn设置为class函数
(defmulti my-print class)
;然后就可以添加针对各种类型的具体实现了
(defmethod name dispatch-val & fn-tail)
;如下是打印字符串的函数
(defmethod my-print String [s]
(.write *out* s))
;如下是打印nil的
(defmethod my-print nil [s]
(.write *out* "nil"))
;还可以添加一个默认实现,即没有匹配的类型时调用
(defmethod my-print :default [s]
(.write *out* "#<")
(.write *out* (.toString s))
(.write *out* ">"))