Clojure功能评估

时间:2015-08-05 22:30:10

标签: java clojure

我正在寻找一个Clojure对数函数,并得出结论,确实没有一个用于v1.3 +。我花了这么长时间来调用Math/log的原因是:

user=> Math/log

CompilerException java.lang.RuntimeException: Unable to find static field: log in class java.lang.Math, compiling:(NO_SOURCE_PATH:0:0)

我尝试了(use 'java.lang.Math)之类的变体等等。直到我尝试了一个例子,我发现它毕竟在那里:

user=> (Math/log 10)
2.302585092994046

这必须是设计,但原因是什么?

3 个答案:

答案 0 :(得分:3)

Clojure提供了一些与Java类,方法和字段进行互操作的表单。当您访问类中的静态字段时,可以这样执行:

user=> Integer/MAX_VALUE
;=> 2147483647
user=> Math/PI
;=> 3.141592653589793

如果要调用静态方法,可以使用以下格式

user=> (Math/log 10)
;=> 2.302585092994046
user=> (Math/sin 1)
;=> 0.8414709848078965

当您尝试仅评估Math/log时,clojure认为它是静态字段,这不是真的。

user=> Math/log

;=> CompilerException java.lang.RuntimeException: Unable to find static field: log in class java.lang.Math, compiling:(/private/var/folders/jh/q738l9dn0hxg0vvwbty7m5hw0000gp/T/form-init145007798854806400.clj:1:5845)

您可以在错误消息(Unable to find static field:...)中看到clojure REPL尝试从log类中找到静态字段Math,然后失败。

答案 1 :(得分:3)

从Java导入的静态方法不是Clojure函数或任何其他类型的Clojure对象。编译器将任何错配报告为缺失字段,即使上下文正在寻找函数。所有这些...

Math/log
(Math/log)
(map Math/log (range 1 5))

......产生这样的错误。

对于相应的Clojure函数:

  • inc返回功能;
  • (inc)举报... wrong number of args(0) ...;
  • (map inc (range 1 5))返回(2 3 4 5)

您可以将Java方法包装为Clojure:

(defn log [x] (Math/log x))

......获得预期结果:

(map log (range 1 5))
;(0.0 0.6931471805599453 1.0986122886681098 1.3862943611198906)

Clojure Java Interop页面推荐

(map #(Math/log %) (range 1 5))

......在这种情况下。

答案 2 :(得分:1)

在Java中,使用括号来调用函数:

println("hi");

Clojure还使用括号来调用函数,但使用不同的位置:

(println "hi")

在Java或Clojure中,只需输入:

println

是一个错误,因为您没有括号来指示函数调用。

在第一个示例中,您使用函数Math / log的名称,但没有括号来告诉REPL您想要调用函数。

此外,在Java中,括号可以指示函数调用或分组运算符:

println(2 + (3 + 4))

在Clojure中,括号 表示函数调用, 从不 表示简单分组。