在Clojure/ClojureScript中的私有def

77

在Clojure和clojurescript中,您可以拥有名为defn-的defn私有版本,但是对于def,如何做到相同的效果,因为似乎没有包含def-?

5个回答

111

你需要添加:private true元数据键值对。

(def ^{:private true} some-var :value)
;; or
(def ^:private some-var :value)
第二种形式只是第一种形式的简写方式。

19
值得一提的是,目前在ClojureScript中无法使用私有的def(以及defn),参见https://clojurescript.org/about/differences(在“特殊形式”下)。
虽然编译不会失败,但def仍将保持可访问性。

16

如果你想要一个默认值,这里是如何实现它的

(defmacro def- [item value]
  `(def ^{:private true} ~item ~value)
)

8
这实际上是行不通的,详见此帖 https://groups.google.com/forum/#!topic/clojure/O7xWh72zzuo 。正确的宏是(defmacro def- [sym init] \(def ~(with-meta sym {:private true}) ~init))`。 - ark
1
@ark 这样做更好,但缺少对文档字符串的支持。请参见我的答案,其中实现几乎与defn-相同。 - John

10

这个Google组内 帖子 讨论了这个主题。 显然,该要求已被考虑过。 根据其中一条回复,认为defn- 不是一个好的想法,并决定不继续使用它,包括def和其他类似函数。


我从链接的帖子中得出的结论是,clojure.core 不是 defn- 的适当位置,而不是 defn- 完全不好。感谢提供链接! - beluchin

9

以下是如何实现def-

(defmacro def-
  "same as def, yielding non-public def"
  [name & decls]
  (list* `def (with-meta name (assoc (meta name) :private true)) decls))

这段代码与defn-非常相似,您可以使用(clojure.repl/source defn-)进行查找:

(defmacro defn-
  "same as defn, yielding non-public def"
  {:added "1.0"}
  [name & decls]
  (list* `defn (with-meta name (assoc (meta name) :private true)) decls))

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接