两种写法似乎都在声明私有函数,和大多数面向对象语言类似。它们的行为有区别,还是其中一种只是语法糖?
我在定义 ring 应用处理函数的代码里见过 defn ^:private。
两种写法似乎都在声明私有函数,和大多数面向对象语言类似。它们的行为有区别,还是其中一种只是语法糖?
我在定义 ring 应用处理函数的代码里见过 defn ^:private。
Each appears to declare a private function, as in most object-oriented languages. Do they behave differently, or does one merely provide syntactic sugur?
I've encountered defn ^:private in code defining a ring application's handler function.
defn- 宏只是“私有”函数声明的简写。完整写出来是这样。
(defn ^:private entry [inputs] ...)
实际上,这只是提醒用户不要使用这些函数。为了测试等用途,绕过这种有限的“私有”保护很简单。因为太麻烦,我不用所谓的“私有”函数(有时会添加 ^:no-doc 元数据,并使用 entry-impl 这样的名称,表明这个 fn 不属于公开 API,库的使用者应该忽略它)。
更多细节可以查看 Clojure 源码对 defn- 的定义 (https://github.com/clojure/clojure/blob/38bafca9e76cd6625d8dce5fb6d16b87845c8b9d/src/clj/clojure/core.clj#L4925)。
The defn- macro simply abbreviates a "private" function declaration. Written out fully, it becomes:
(defn ^:private entry [inputs] ...)
This is really only a signal to users to avoid those functions. Bypassing this limited "private" protection for testing and similar tasks is straightforward. I avoid so-called "private" functions because of the inconvenience (occasionally I attach ^:no-doc metadata and choose names such as entry-impl to show a fn isn't within the public API and library consumers ought to disregard it).
For additional details, inspect how Clojure source code defines defn- (https://github.com/clojure/clojure/blob/38bafca9e76cd6625d8dce5fb6d16b87845c8b9d/src/clj/clojure/core.clj#L4925).
回答最初的问题,它们是等价的。
user=> (defn- first_fn [value] value)
#'user/first_fn
user=> (defn ^:private second_fn [value] value)
#'user/second_fn
user=> (meta #'first_fn)
{:private true, :arglists ([value]), :line 1, :column 1, :file "NO_SOURCE_PATH", :name first_fn, :ns #object[clojure.lang.Namespace 0xcaf2cc4 "user"]}
user=> (meta #'second_fn)
{:private true, :arglists ([value]), :line 1, :column 1, :file "NO_SOURCE_PATH", :name second_fn, :ns #object[clojure.lang.Namespace 0xcaf2cc4 "user"]}
user=> (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))
nil
user=>
查看 defn- 的实现可以发现,它的行为和给 name 符号添加了 :private true 元数据的 defn 完全一样。
To address what was asked originally: they are equivalent.
user=> (defn- first_fn [value] value)
#'user/first_fn
user=> (defn ^:private second_fn [value] value)
#'user/second_fn
user=> (meta #'first_fn)
{:private true, :arglists ([value]), :line 1, :column 1, :file "NO_SOURCE_PATH", :name first_fn, :ns #object[clojure.lang.Namespace 0xcaf2cc4 "user"]}
user=> (meta #'second_fn)
{:private true, :arglists ([value]), :line 1, :column 1, :file "NO_SOURCE_PATH", :name second_fn, :ns #object[clojure.lang.Namespace 0xcaf2cc4 "user"]}
user=> (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))
nil
user=>
Examining the implementation of defn- shows it behaves exactly like defn after attaching :private true metadata to the name symbol.
这是我在 GDScript 中使用的枚举声明。 我想随机选择一个枚举变体,而不用列出所有可能的变体。这样以后增加变体时,就不必修改负责随机选择的代码。 我尝试过下面这种方法。 还有这一种。 两种都失败了。一个返回 Null,另一个报告 "Invali…
Nim 中怎样表示求余运算? cell % 7 == 0 会给出 undeclared identifier: '%' 这个错误 Google 搜索和查看 SO 都没找到答案。
怎样才能让函数在执行结束后返回一个值? 例如我有这样的代码。 ROUTINE N ? N ⍴ 12 //它会生成 N 个从 1 到 12 的随机值 (N 是函数的参数)。 我只是想知道怎样拿到函数的结果,然后比如把这个结果传给另一个函数。 谢谢大家的…