我希望能够采用多种方法,将其克隆为单独的变量并添加到其中而不更改原始变量。如何做到这一点?
(defmulti hello :type)
(defmethod hello :a
[e] (assoc e :a 1))
(hello {:type :a})
=> {:type :a :a 1}
;; my attempt at cloning
(def world @#'hello)
(defmethod world :b
[e] (assoc e :b 2))
(world {:type :b})
=> {:type :b :b 2}
;; I want this to throw... but because `hello` and `world`
;; are the same function, it still works
(hello {:type :b})
=> {:type :b :b 2}
最佳答案
通过查看 https://github.com/clojure/clojure/blob/master/src/clj/clojure/core.clj#L1769-L1777 找出答案:
(defn clone
[multi name]
(let [table (.getMethodTable multi)
clone (clojure.lang.MultiFn. name
(.dispatchFn multi)
(.defaultDispatchVal multi)
(.hierarchy multi)]
(doseq [[dispatch-val method] table]
(.addMethod clone dispatch-val method))
clone))
----回到原来的问题----
(defmulti hello :type)
(defmethod hello :a
[e] (assoc e :a 1))
(def world (clone hello "world"))
(defmethod world :b
[e] (assoc e :b 2))
(world {:type :b})
=> {:type :b :b 2}
(hello {:type :b})
=> (throws)
关于clojure - 是否可以克隆多方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39793291/