鉴于以下代码:
(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的功能真的),所以没有静电场parseInt
中Integer 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"])
它在尝试获取字段时失败(您认为它正在获取对方法的引用).
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问题可以帮助您了解发生了什么。
归档时间: |
|
查看次数: |
2401 次 |
最近记录: |