如何在 Clojure / Clojurescript 中重用 deftype 方法?
How to reuse deftype methods in Clojure / Clojurescript?
我正在尝试扩展库 DomKM/silk。
具体来说,deftype Route
实现了协议 Pattern
,它具有方法实现,我想在 Pattern
协议的自定义实现中重用它。
https://github.com/DomKM/silk/blob/master/src/domkm/silk.cljx#L355
(deftype Route [name pattern]
Pattern
(-match [this -url]
(when-let [params (match pattern (url -url))]
(assoc params ::name name ::pattern pattern)))
(-unmatch [this params]
(->> (dissoc params ::name ::pattern)
(unmatch pattern)
url))
(-match-validator [_]
map?)
(-unmatch-validators [_]
{}))
好的,所以我的实现看起来有点像这样,但我想要 "inherit" Route
的方法。我的意思是先执行一些自定义逻辑,然后将其传递给原始 Route
方法。
(deftype MyRoute [name pattern]
silk/Pattern
(-match [this -url]
true) ;match logic here
(-unmatch [this {nm ::name :as params}]
true) ;unmatch logic here
(-match-validator [_] map?)
(-unmatch-validators [_] {}))
这是如何在 clojure / clojurescript 中完成的?
无需重新定义类型。从另一个名称空间引用 "ancestor" 协议实现是可能的。
user=> (ns ns1)
nil
ns1=> (defprotocol P (f [o]))
P
ns1=> (deftype T [] P (f [_] 1))
ns1.T
ns1=> (f (T.))
1
ns1=> (ns ns2)
nil
ns2=> (defprotocol P (f [o]))
P
ns2=> (extend-protocol P ns1.T (f [o] (+ 1 (ns1/f o))))
nil
ns2=> (f (ns1.T.))
2
请记住 ns1.P
和 ns2.P
是完全不同的猫,都叫 P
。
我正在尝试扩展库 DomKM/silk。
具体来说,deftype Route
实现了协议 Pattern
,它具有方法实现,我想在 Pattern
协议的自定义实现中重用它。
https://github.com/DomKM/silk/blob/master/src/domkm/silk.cljx#L355
(deftype Route [name pattern]
Pattern
(-match [this -url]
(when-let [params (match pattern (url -url))]
(assoc params ::name name ::pattern pattern)))
(-unmatch [this params]
(->> (dissoc params ::name ::pattern)
(unmatch pattern)
url))
(-match-validator [_]
map?)
(-unmatch-validators [_]
{}))
好的,所以我的实现看起来有点像这样,但我想要 "inherit" Route
的方法。我的意思是先执行一些自定义逻辑,然后将其传递给原始 Route
方法。
(deftype MyRoute [name pattern]
silk/Pattern
(-match [this -url]
true) ;match logic here
(-unmatch [this {nm ::name :as params}]
true) ;unmatch logic here
(-match-validator [_] map?)
(-unmatch-validators [_] {}))
这是如何在 clojure / clojurescript 中完成的?
无需重新定义类型。从另一个名称空间引用 "ancestor" 协议实现是可能的。
user=> (ns ns1)
nil
ns1=> (defprotocol P (f [o]))
P
ns1=> (deftype T [] P (f [_] 1))
ns1.T
ns1=> (f (T.))
1
ns1=> (ns ns2)
nil
ns2=> (defprotocol P (f [o]))
P
ns2=> (extend-protocol P ns1.T (f [o] (+ 1 (ns1/f o))))
nil
ns2=> (f (ns1.T.))
2
请记住 ns1.P
和 ns2.P
是完全不同的猫,都叫 P
。