如何将静态方法传递给clojure中的comp?

时间:2010-02-05 17:00:47

标签: string vector clojure integer

好像我在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

2 个答案:

答案 0 :(得分:27)

Clojure函数是java方法,但java方法不是clojure函数例如Clojure函数有元数据等。如果你想使用一个调用Clojure函数的java方法,那么你有两个选择来包装它,memfnfun 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 %)))

partialcomp在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 %)))

取决于您是否希望能够处理除整数之外的其他内容。