我有这个宏:
(defmacro widget [msg-type value & app-key]
`(defrecord ~msg-type [~value]
Message
(~'process-message [msg# app#]
(let [state# (~@app-key app#)]
(dissoc
(->>
(merge state# msg#)
(assoc app# ~@app-key))
:errors)))))
Message
是a clojurescript dependency中定义的协议,具有process-message
功能。
当我尝试使用widget
时,
(ns my.cljs.ns
(:require-macros [my.ns.macros :as macro])
(:require [petrol.core :refer [Message]]))
(macro/widget A-Record a-field :a-key)
我收到此错误:
Bad method signature in protocol implementation,
my.ns.macros/Message does not declare method called
process-message ...
如何让消息引用petrol/Message
而不是my.ns.macros/Message
?
答案 0 :(得分:2)
你需要神秘的力量〜'运营商:) 我看到你已经调用了它来处理进程消息,所以也许你已经熟悉了为什么;但是为了答案的目的,反引号中的内容获得完全命名空间限定,其中评估引用将文字符号放在适当的位置。
public class test {
public int sumOfDigits(String s) {
int sum = 0;
for (int i=0; i<s.length(); i++) {
char cur = s.charAt(i);
if (cur >= 0 && cur <= 9) {
sum += cur - '0';
}
}
return sum;
}
}
如果您想避免将当前ns附加到其上,则错误消息表明您需要(macroexpand-1 '(widget :a :b))
。
然而,具有汽油命名空间的完全符合条件的消息将是一个很好的举动IMO
~'Message
这样你就不需要依赖ns声明中的引用了。请注意,您不需要〜&#39;它要么。
另外我会警惕(〜@ app-key app#),因为app-key是可选的...你可以得到任何东西,它会调用#app是什么,这听起来不像是什么东西你想要发生。同样地传递不止一个似乎很奇怪。也许它应该是必需的参数?