我正在尝试使用原始参数在Clojure 1.4中定义一个协议(这样我就可以避免在性能敏感的代码中出现不必要的原始装箱):
(defprotocol A
(foo [a ^long x]))
(extend-type java.lang.String A
(foo [s ^long x] (.charAt s x)))
这看起来好像可以正常但在我尝试使用它时失败并出现异常:
(foo "abracadarbra" 3)
=> ClassCastException XXXX cannot be cast to clojure.lang.IFn$OLO
我做错了什么?
答案 0 :(得分:3)
经过一些进一步的研究后,似乎协议还不支持原始类型提示(截至Clojure 1.4)。参见例如https://groups.google.com/d/topic/clojure-dev/HxBqIewc494/discussion
替代品似乎是:
答案 1 :(得分:2)
从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
编辑:
(extend-type java.lang.String A
(foo [s ^Long x] (type x)))
nil
core> (foo "abracadarbra" 3)
java.lang.Long