I'm learning Clojure and am confused by the following:
(vector "1")
;; returns ["1"]
(开发者_开发知识库map vector '("1" "2" "3"))
;; returns (["1"] ["2"] ["3"])
However:
(Integer/parseInt "1")
;; returns 1
(map Integer/parseInt '("1" "2" "3"))
;; throws error "Unable to find static field: parseInt in class java.lang.Integer"
Instead, I need:
(map #(Integer/parseInt %) '("1" "2" "3"))
;; returns (1 2 3)
If I can use a function like vector
with map
, why can't I use Integer/parseInt
?
You have to wrap it in #()
or (fn ...)
. This is because Integer/parseInt is a Java method and Java methods can't be passed around. They don't implement the IFn
interface.
Clojure is built on Java and sometimes this leaks through, and this is one of those cases.
As others have stated, you need to wrap Integer/parseInt in order to convert it from a Java method into a Clojure function:
(map #(Integer/parseInt %) '("1" "2" "3"))
The reason for this is that Clojure functions must implement the IFn interface in order to be passed as arguments into higher order functions such as map
.
This is a little bit ugly if you are doing this kind of conversion many times, so I'd recommend wrapping your parse-int function as follows:
(defn parse-int [s] (Integer/parseInt s))
(map parse-int '("1" "2" "3"))
As a final alternative, you may want to use the built-in read-string function - this will return integers in your case but would also work for doubles etc.:
(map read-string '("1" "2" "3"))
Have a look at the Stack Overflow question Convert a sequence of strings to integers (Clojure). The answer says: You have to wrap Integer/parseInt in an anonymous function because Java methods aren't functions.
精彩评论