Clojure:无法找到静态字段

hey*_*rne 15 clojure

鉴于以下代码:

(map Integer/parseInt ["1" "2" "3" "4"])
Run Code Online (Sandbox Code Playgroud)

为什么我得到以下异常,除非我包装Integer/parseInt匿名函数并手动调用它(#(Integer/parseInt %))?

clojure.lang.Compiler$CompilerException: java.lang.RuntimeException: Unable to find static field: parseInt in class java.lang.Integer
Run Code Online (Sandbox Code Playgroud)

lee*_*ski 21

关于java interop的文档说明如下:

上面给出了用于访问字段或方法成员的优选惯用形式.实例成员表单适用于字段和方法.如果字段和同名的0参数方法都存在,则instanceField表单是字段的首选表单.它们都扩展为在宏扩展时调用点运算符(如下所述).的扩展如下:...(类名/ STATICMETHOD ARGS*)==>(类名STATICMETHOD ARGS*)类名/ staticField ==>(类名称staticField)

所以你应该记住,这Class/fieldName仅仅是用于获取静态糖领域,无论是静态方法调用,也不参考静态方法(Java方法是不是一个Clojure的功能真的),所以没有静电场parseIntInteger class,而(Class/fieldName arg)调用静态方法,它们是两个完全不同的操作,使用类似的含糖语法.

所以当你这样做(map #(Integer/parseInt %) ["1" "2" "3" "4"])扩展到

(map #(. Integer parseInt %) ["1" "2" "3" "4"])

(您可以通过宏扩展轻松看到它),

(map Integer/parseInt ["1" "2" "3"])扩展到

(map (. Integer parseInt) ["1" "2" "3"])

它在尝试获取字段时失败(您认为它正在获取对方法的引用).


nta*_*lbs 5

Integer/parseInt是静态的Integer类方法,而不是clojure函数。每个clojure函数都被编译为实现clojure.lang.IFn接口的java类。map期望clojure函数(实现IFn接口)作为第一个参数,但Integer/parseInt不是。

您可以在clojure repl中进行检查。

user=> (type map)
clojure.core$map
user=> (type Integer)
java.lang.Class
user=> (type Integer/parseInt)

CompilerException java.lang.RuntimeException: Unable to find static field: parseInt in class java.lang.Integer, compiling:(/private/var/folders/p_/psdvlp_12sdcxq07pp07p_ycs_v5qf/T/form-init4110003279275246905.clj:1:1)

user=> (defn f [] 1)
#'user/f
user=> (type f)
user$f
user=> (type #(1))
user$eval9947$fn__9948
Run Code Online (Sandbox Code Playgroud)

也许阅读这个stackoverflow问题可以帮助您了解发生了什么。