库函数与Clojure中的Java方法

时间:2014-08-22 05:13:43

标签: java function clojure

在阅读'Programming Clojure'时,我注意到在Clojure中有其他方法可以执行某些操作。例如,假设我们需要将字符串的所有字符转换为大写的变体。

我们可以使用.toUpperCase

user> (.toUpperCase "foo")
;; => "FOO"

以及clojure.string/upper-case

user> (clojure.string/upper-case "foo")
;; => "FOO"

虽然clojure.string/upper-case是一个功能,我们可以这样对待它:

user> (map clojure.string/upper-case ["foo" "bar" "baz"])
;; => ("FOO" "BAR" "BAZ")

...我们不能对.toUpperCase执行相同的操作:

user> (map .toUpperCase ["foo" "bar" "baz"])
CompilerException java.lang.RuntimeException: Unable to resolve symbol...

我猜.toUpperCase是Java方法的直接调用,Clojure知道如何处理这个符号,当它是表单的第一个元素时。

:我应该使用.toUpperCaseclojure.string/upper-case以及它们之间的区别:

(map clojure.string/upper-case ["foo" "bar" "baz"])

(map (fn [x] (.toUpperCase x)) ["foo" "bar" "baz"])

2 个答案:

答案 0 :(得分:7)

要么有效:它基本上是一个权衡如下:

包装Clojure函数的优点:

  • 更多惯用的Clojure风格
  • 更可能是可移植的(例如ClojureScript)
  • 可以传递给更高阶的函数

使用Java方法的优点:

  • 性能稍好(假设您正确使用类型提示以避免反射)
  • 如果您正在使用Java程序员/ Java代码库,那就更透明了

通常情况下,我更喜欢使用包装的Clojure函数,除非我已经对基准测试并确定了性能问题,此时我可能会直接使用Java互操作。

答案 1 :(得分:6)

clojure.string/upper-case只是java.lang.String.toUpperCase方法的包装函数。您可以在您的代表中办理登机手续。

user=> (source clojure.string/upper-case)
(defn ^String upper-case
  "Converts string to all upper-case."
  {:added "1.2"}
  [^CharSequence s]
  (.. s toString toUpperCase))

如您所见,upper-case只需调用toUpperCase

我认为没有任何强有力的规则只能在他们之间选择一个。但是,正如您所知,.toUpperCase方法不是clojure函数,不能作为参数传递给其他高阶函数。因此,如果您没有任何具体原因可以使用clojure.string/upper-case方法,最好使用.toUpperCase