4

考虑以下 Clojure 代码:

(defn space? [c] (Character/isWhitespace c))

没关系。但显然,这只是另一个名称和毫无意义的重构:

(def space? Character/isWhitespace)

但我得到编译错误:

Caused by: java.lang.RuntimeException: Unable to find static field: isWhitespace 
in class java.lang.Character

为什么它找不到?它与 Clojure 函数完美配合:

(def wrap-space? space?) ; Compiles OK!

这里会发生什么?为什么def使用 Java 静态函数不起作用?

4

1 回答 1

7

您的前两个陈述实际上是不等价的。当你说...

(def space? Character/isWhitespace)

... Clojure 正在尝试查找isWhitespacejava.lang.Character. 当然,不存在这样的字段,这就是您收到编译错误的原因。

重写以下语句的其他正确方法...

(defn space? [c] (Character/isWhitespace c))

...将会:

  • (def space? (fn [c] (Character/isWhitespace c)))
  • (defn space? [c] (. Character isWhitespace c))

编辑

补充一点,我想 Clojure 允许的原因(def wrap-space? space?)是因为它没有歧义space?。另一方面,静态 Java 方法可以使用不同的参数集进行重载,或者可以与静态字段共享相同的名称。因此,要为静态 Java 方法设置别名,您必须明确说明您正在为哪个方法/字段设置别名。

于 2013-09-02T23:01:53.503 回答