Clojure 找不到原生类的 java 构造函数?



我想创建一个函数,它可以传递函数映射并将这些函数应用于另一个映射——可以将其视为将字符串映射强制转换为任意类型。(我想做一些更高级的东西,比如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。很长,很有趣:

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

我可以这样写我的代码,虽然它看起来有点…假吗?

不管怎样,这是怎么回事?为什么说得通呢?

Java函数,包括构造函数,不是合法的Clojure函数,不能直接传递给像apply这样的高阶函数,除非它们被包装在Clojure函数中。

另外,注意apply需要一个参数集合,因为它从数组中"解包裹"它们。这适用于只有一个字符串的vector:

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

但是你真正想要的可能是mapvmap:

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

我会让你找出这些失败案例的问题所在:

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

最新更新