How do I pass a static method to comp in clojure?
It seems as though I'm having problems accessing Integer.parseInt
in comp. I can access it normally like this:
user=> (Integer/parseInt "123")
123
But if I put it in comp, I get an error:
user=> (def vect-to-int (comp Integer/parseInt (partial apply str)))
java.lang.Exception: Unable to find static field: parseInt in class java.lang.Integer (NO_SOURCE_F开发者_如何学编程ILE:3)
It sounds to me like it's trying to find a field on Integer when it should be looking for a method. How can I use Integer.parseInt
like this? And is there a better way to convert a vector of chars into an int
?
Clojure functions are java methods but java methods are not clojure functions For instance Clojure functions have meta-data and such. If you want to use a java method where a Clojure function is called for then you have two choices in wrapping it up, memfn
and fun or #( )
memfn is an obsolete function that wrapped up a java method in a clojure function (its good to know it exists even if its not used often). The generally accepted way to wrap up java methods is:
#(. instance method arg1 argN)
or for static methods
#(Class/MethodName arg1 argN)
(def vec-to-int (comp #(Integer/parseInt %) (partial apply str)))
Or
(def vec-to-int #(Integer/parseInt (apply str %)))
partial
and comp
usually aren't as succinct in Clojure as using #()
to make an anonymous fn. Personally I'd write it this way:
(defn vec-to-int [x] (Integer/parseInt (apply str x)))
You can do this with plain def
, but what do you gain using def
instead of defn
, really? Using def
obscures the fact that you're defining a function. defn
also sets up additional metadata for you (arglists) that def
doesn't.
In any case, this is a more general way to do what you're doing:
(def vec-to-int #(bigint (apply str %)))
And still more general:
(def vec-to-int #(read-string (apply str %)))
Depends whether you want to be able to handle things other than Integers.
精彩评论