Clojure 如何获取调用Java方法的Fn?
我在学Clojure。我写这段代码是为了递归地遍历目录Clojure 如何获取调用Java方法的Fn?,clojure,Clojure,我在学Clojure。我写这段代码是为了递归地遍历目录 (tree-seq #(.isDirectory %1) #(.listFiles %1) (File. "/my-directory")) 为什么我不能将.isDirectory用作Clojure中的一级函数?是否有更好的方法重写此代码?您可以查看(使用树序列)以了解其工作原理 顺便说一下:你的代码对我来说非常好。我只需要使用java.io.File而不是REPL中的File,这样它就知道java类了。java方法不是clojure函数
(tree-seq #(.isDirectory %1) #(.listFiles %1) (File. "/my-directory"))
为什么我不能将
.isDirectory
用作Clojure中的一级函数?是否有更好的方法重写此代码?您可以查看(使用树序列)以了解其工作原理
顺便说一下:你的代码对我来说非常好。我只需要使用java.io.File而不是REPL中的File,这样它就知道java类了。java方法不是clojure函数,因为你不能单独调用一个方法;您必须对一个对象调用一个方法,并且它必须是该方法所期望的类型的对象。换句话说,在java中,方法不能与其定义类完全分离(至少不能有效地分离)
#(.foo%)的另一个替代品是(memfn-foo),自从引入了#(…)之后,几乎没有人再使用它了。Joost对Java方法不是第一类函数的说法一针见血 作为一种处理方法,我通常喜欢将Java函数包装到Clojure函数中(或者找到一个已经这样做的库),然后以惯用的一流方式轻松使用它们:
(defn directory? [^java.io.File file]
(.isDirectory file))
(defn list-files [^java.io.File file]
(.listFiles %1))
(tree-seq directory? list-files (File. "/my-directory"))
这是几行代码,但有以下优点:
- 您可以在函数中添加类型提示以避免反射(如上所述)
- 最后的代码更简洁、更地道
- 您已经从底层Java互操作中抽象出来
- 您已经得到了正确的答案,但为了添加更多Clojure惯用代码,我还将使用
#(.foo %)
正如Joost Diepenmaat所做的那样(但我相信它可能被忽略了)
我还建议你读书