Clojure找不到本机类的java构造函数?

时间:2016-08-31 16:13:08

标签: java clojure

我想创建一个函数,我可以传递一个函数映射并将这些函数应用到另一个映射 - 将其视为强制将字符串映射到任意类型。 (我喜欢做更高级别的事情,比如fmap,但一次一步,对吗?)

因此,我认为我需要做一些像

这样的事情
user=> (apply Long. "1")

但是当我尝试时,我得到了这个:

CompilerException java.lang.ClassNotFoundException: Long., compiling:(/private/var/folders/c9/5yl3m9pn0rjdnvqlp5v4fzhr0000gn/T/form-init8437802472507251220.clj:1:1)

我当然可以通过这种方式找到课程:

user=> (Long. "1")
1

如果我这样做

user=> (apply #(Long. %1) "1")

我看到了

IllegalArgumentException No matching ctor found for class java.lang.Long  clojure.lang.Reflector.invokeConstructor (Reflector.java:183)

这令人困惑,因为我刚才使用了构造函数。无论如何,我想我做到了。它甚至找到了正确的类,而不是类的构造函数。

这也失败了,不同的是:

user=> (apply #(new Long. %1) "1")

CompilerException java.lang.ClassNotFoundException: Long., compiling:(/private/var/folders/c9/5yl3m9pn0rjdnvqlp5v4fzhr0000gn/T/form-init8437802472507251220.clj:1:9)

我可以找不到java.lang.Long,这很有趣:

user=> (apply #(new java.lang.Long. %1) "1")

CompilerException java.lang.ClassNotFoundException: java.lang.Long., compiling:(/private/var/folders/c9/5yl3m9pn0rjdnvqlp5v4fzhr0000gn/T/form-init8437802472507251220.clj:1:9)

但这有效:

user=> (defn l [x] (Long. x))
#'user/l
user=> (apply l ["1"])
1

我可以用这种方式编写我的代码,虽然看起来有点......关闭?

无论如何,这里发生了什么?为什么这有意义?

1 个答案:

答案 0 :(得分:1)

Java functions, including constructors, are not legal Clojure functions and cannot be passed directly to higher-order-functions like apply unless they are wrapped inside a Clojure function.

Also, note that apply expects an collection of args, as it "unwraps" them from the array. This works for a vector with one string:

(Long. "1")  -> 1
(apply #(Long. %) ["1"] )  -> 1

But what you really probably want is mapv or map:

(mapv #(Long. %) ["1" "2" "3"] )  -> [1 2 3]

I'll let you figure out whats wrong with these failing cases:

; failing cases
; (apply Long. ["1"] )
; (apply #(Long. %) ["1" "2" "3"] )
; (apply #(Long. %) "1" "2" ["3"] )