正如这里所说的那样,私有的clojure函数并不是真正的私有,只是隐藏.我不喜欢这个.在java中,标记为private的函数不能在类外调用而不会抛出编译错误.有没有办法确保我声明为私有的方法真的是私有的,没有其他人可以调用它们?有没有办法至少模拟这个?
为了使我们的术语直截了当,Java 8有java.util.function.Function,但我认为你实际上是指java 方法.Clojure函数(实现clojure.lang.IFn接口的类)不是方法,而是类.IFn扩展Runnable和Callable接口.
严格地说,你可以通过实现词法闭包来实际隐藏Clojure函数,这样就没有可以暴露它的可访问Object.
例如:
(ns my.hidden)
(fn not-here
[x]
(println "this can never be called"))
Run Code Online (Sandbox Code Playgroud)
没有代码可以调用此函数.这个函数是如此隐藏,垃圾收集器可能会在创建它后立即将其从vm中删除.当然这没有用.
一个更现实的例子(但你可能不应该这样做):
(ns my.discreet)
(letfn [(a [x] (println "a with" x))
(b [x] (println "b with" x))]
(defn foo [x]
(if (> (rand) 0.5)
(a x)
(b x))))
Run Code Online (Sandbox Code Playgroud)
在这里,呼叫者没有直接访问a或b的便捷方式.通过反射可以实现,但只能利用Clojure版本的已知实现细节.没有API,因此任何解决方案都将依赖于实现.引用一位Clojure开发人员的话说:"如果我这样做的话,就会滥用实施细节,我觉得这样做不舒服".
但重要的是隐藏这些功能实际上并不是做Clojure的惯用方法.在Clojure中,当我们要在防守代码,我们宁愿在不可改变的数据类型,这确保无知或恶意程序员不能导致无效状态,因为我们不是靠状态的突变来实现我们的算法计算.