好像我在comp中访问Integer.parseInt
时遇到了问题。我可以像这样访问它:
user=> (Integer/parseInt "123")
123
但是如果我把它放在comp中,我会收到一个错误:
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_FILE:3)
听起来我觉得它应该在寻找方法时尝试在Integer上找到一个字段。我该如何使用Integer.parseInt
这样的?是否有更好的方法将字符向量转换为int
?
答案 0 :(得分:27)
Clojure函数是java方法,但java方法不是clojure函数例如Clojure函数有元数据等。如果你想使用一个调用Clojure函数的java方法,那么你有两个选择来包装它,memfn
和fun or #( )
memfn是一个过时的函数,它在一个clojure中包装了一个java方法功能(即使它不经常使用也很好知道它存在)。包含java方法的普遍接受的方法是:
#(. instance method arg1 argN)
或静态方法
#(Class/MethodName arg1 argN)
答案 1 :(得分:7)
(def vec-to-int (comp #(Integer/parseInt %) (partial apply str)))
或者
(def vec-to-int #(Integer/parseInt (apply str %)))
partial
和comp
在Clojure中通常不像使用#()
制作匿名fn那样简洁。就个人而言,我会这样写:
(defn vec-to-int [x] (Integer/parseInt (apply str x)))
您可以使用普通def
执行此操作,但使用def
代替defn
获得了什么?使用def
掩盖了您正在定义函数的事实。 defn
还为您(arglists)设置了def
没有的其他元数据。
无论如何,这是一种更通用的方式来做你正在做的事情:
(def vec-to-int #(bigint (apply str %)))
更为一般:
(def vec-to-int #(read-string (apply str %)))
取决于您是否希望能够处理除整数之外的其他内容。