clojure - 是否可以克隆多方法?

标签 clojure

我希望能够采用多种方法,将其克隆为单独的变量并添加到其中而不更改原始变量。如何做到这一点?

(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/

相关文章:

web-applications - 带有 Clojure 的“丰富”网络应用程序

Heroku + Clojure (webnoir),如何做到lein clean?

clojure - Kafka MockConsumer 未收到记录

clojure - 在抛出异常之前重试某件事 3 次 - 在 clojure 中

data-structures - PersistentQueue 的 API 是什么?

clojure - Clojure 的 STM 值历史可以访问吗?

clojure - 如何在 korma 中选择默认字段?

Clojure 的重构技术

clojure - lein 导致 jline3 终端变得愚蠢

serialization - 如何快速将 Clojure 数据结构序列化为带有缩进的字符串?