2012-08-28 50 views
3

我试图定义的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 

我在做什么错?

回答

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 
+0

感谢亚瑟!这有效 - 但它实际上是使用函数的原始版本吗? – mikera

+0

它似乎不是......: -/ –

+0

嗯,不完全解决这个问题,然后我的意图是找到一种方法来避免拳击原始参数..... – mikera