【问题标题】:Usage of java methods as a function argument in Clojure在 Clojure 中使用 java 方法作为函数参数
【发布时间】:2014-04-16 19:26:50
【问题描述】:

如何在 Clojure 中使用 java 方法作为函数参数?

例如,我想做一个函数组合:

user> (Integer. (str \9))
9
user> ((comp Integer. str) \9)
CompilerException java.lang.ClassNotFoundException: Integer., compiling:(NO_SOURCE_PATH:1:2) 

这行不通。

memfn 也无济于事:

user> (map (comp (memfn  Integer.) str) "891")
IllegalArgumentException No matching method found: Integer. for class java.lang.String  clojure.lang.Reflector.invokeMatchingMethod (Reflector.java:53)

有什么想法吗?

相关问题(不过,没有给出正确答案):

(注意:dave 建议的答案似乎是使用匿名函数作为包装器,是最好的解决方案)

【问题讨论】:

    标签: java clojure


    【解决方案1】:

    与 Clojure 函数不同,Java 方法并非设计为一流的。当您在 Clojure 中使用 Java 互操作时,您实际上是在使用 Java 方法,因此您不会获得为 Clojure 函数实现的额外好处。有关详细信息,请参阅下面的 cmets。

    作为使用 Java 方法作为参数的一种解决方法,您可以将它们包装在匿名函数中,就像这样,有效地使它们成为 Clojure 函数:

    ((comp #(Integer. %) str) \9)
    

    【讨论】:

    • 戴夫,谢谢,总比没有好,但我希望还有其他方法(+1)
    • 为什么 Clojure 方法不是函数? Clojure 函数是符合IFn 接口的Java 对象,它有一堆invoke 方法,最多可达20 个,以及几种调用无限长参数列表的方法。所有这些都接受 Java Object 参数并返回 Java Object。你可以在github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/…找到IFn
    • 它们不是一流的,因为在我看来,选择要么具有不是真正一流的值的函数(使语言更弱),要么抽象所有 jvm 方法,因此它们就像真正的函数一样(使语言过于复杂)。
    • 我也很好奇,想知道为什么不能将 Java 方法用作函数。我对 Java 了解不多,但我的猜测是 Java 方法在 Java 中不是一流的,所以 Clojure 将此功能添加到自己的函数中,但是当您使用 Java 互操作时,您实际上是在处理 Java方法,因此您不会获得使用 Clojure 函数所获得的额外好处。
    • 没错。 Clojure 保持其互操作层尽可能小和简单,方法根本不应该是一流的。
    猜你喜欢
    • 1970-01-01
    • 2010-12-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-22
    • 2021-11-21
    相关资源
    最近更新 更多