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

Jas*_*ker 24 string integer vector clojure

好像我Integer.parseInt在comp中访问时遇到了问题.我可以像这样正常访问它:

user=> (Integer/parseInt "123")
123
Run Code Online (Sandbox Code Playgroud)

但如果我把它放在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)
Run Code Online (Sandbox Code Playgroud)

听起来我觉得它应该在寻找方法时尝试在Integer上找到一个字段.我Integer.parseInt该怎么用?是否有更好的方法将字符向量转换为int

Art*_*ldt 28

Clojure函数是java方法,但java方法不是clojure函数.例如,Clojure函数具有元数据等.如果你想使用一个调用Clojure函数的java方法,那么你有两个选择来包装它,memfnfun or #( )memfn是一个过时的函数,它在一个clojure函数中包含了一个java方法(即使它存在,也很好知道它存在)它经常不用).包含java方法的普遍接受的方法是:

#(. instance method arg1 argN)  
Run Code Online (Sandbox Code Playgroud)

或者用于静态方法

#(Class/MethodName arg1 argN)
Run Code Online (Sandbox Code Playgroud)


Bri*_*per 7

(def vec-to-int (comp #(Integer/parseInt %) (partial apply str)))
Run Code Online (Sandbox Code Playgroud)

要么

(def vec-to-int #(Integer/parseInt (apply str %)))
Run Code Online (Sandbox Code Playgroud)

partial并且comp在Clojure中通常不像使用#()匿名fn 那样简洁.就个人而言,我会这样写:

(defn vec-to-int [x] (Integer/parseInt (apply str x)))
Run Code Online (Sandbox Code Playgroud)

你可以用普通的方式做到这一点def,但你用什么def代替defn呢?使用def模糊了你定义一个函数的事实. defn还为您(arglists)设置了其他元数据def.

无论如何,这是一种更通用的方式来做你正在做的事情:

(def vec-to-int #(bigint (apply str %)))
Run Code Online (Sandbox Code Playgroud)

更一般的是:

(def vec-to-int #(read-string (apply str %)))
Run Code Online (Sandbox Code Playgroud)

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