Clojure 使用带有原始参数的协议
我正试图在Clojure 1.4中使用原语参数定义一个协议(这样我就可以避免在性能敏感代码中不必要的原语装箱): 这看起来工作正常,但在我尝试使用它时出现异常:Clojure 使用带有原始参数的协议,clojure,protocols,primitive,Clojure,Protocols,Primitive,我正试图在Clojure 1.4中使用原语参数定义一个协议(这样我就可以避免在性能敏感代码中不必要的原语装箱): 这看起来工作正常,但在我尝试使用它时出现异常: (foo "abracadarbra" 3) => ClassCastException XXXX cannot be cast to clojure.lang.IFn$OLO 我做错了什么?从defprotocol中取出类型提示,并将其保留在extend type (defprotocol A (foo [a x])) (e
(foo "abracadarbra" 3)
=> ClassCastException XXXX cannot be cast to clojure.lang.IFn$OLO
我做错了什么?从
defprotocol
中取出类型提示,并将其保留在extend type
(defprotocol A
(foo [a x]))
(extend-type java.lang.String A
(foo [s ^Long x] (.charAt s x)))
nil
core> (foo "abracadarbra" 3)
\a
或者您可以更改类型提示,如下所示:
(defprotocol A
(foo [a ^Long/TYPE x]))
(extend-type java.lang.String A
(foo [s ^long x] (.charAt s x)))
nil
core> (foo "abracadarbra" 3)
\a
如果没有defprotocol
编辑:
在进一步研究之后,协议似乎还不支持原语类型提示(从Clojure 1.4开始)。见例 替代方案似乎是:
- 编写带有基本提示的常规函数。你失去了多态性
- 使用Java接口(可用于在Clojure中构建实例)
(defprotocol A
(foo [a ^Long/TYPE x]))
(extend-type java.lang.String A
(foo [s ^long x] (.charAt s x)))
nil
core> (foo "abracadarbra" 3)
\a
(extend-type java.lang.String A
(foo [s ^Long x] (type x)))
nil
core> (foo "abracadarbra" 3)
java.lang.Long