openlang

Clojure 的 defn- 与带 ^:private 的函数声明有区别吗?

两种写法似乎都在声明私有函数,和大多数面向对象语言类似。它们的行为有区别,还是其中一种只是语法糖?

我在定义 ring 应用处理函数的代码里见过 defn ^:private。

从英语翻译查看原文

后续讨论 2

顺着彼此的依据读下去
  1. 固定链接

    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)。

    从英语翻译查看原文
  2. 固定链接

    回答最初的问题,它们是等价的。

    
    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 完全一样。

    从英语翻译查看原文

同一个问题的其他角度

  1. 在 Godot 3.3 的 GDScript 中怎样随机选择枚举项而不用逐项列出?

    这是我在 GDScript 中使用的枚举声明。 我想随机选择一个枚举变体,而不用列出所有可能的变体。这样以后增加变体时,就不必修改负责随机选择的代码。 我尝试过下面这种方法。 还有这一种。 两种都失败了。一个返回 Null,另一个报告 "Invali…

    回复 2最近活动 gdscript
  2. Nim 求余语法

    Nim 中怎样表示求余运算? cell % 7 == 0 会给出 undeclared identifier: '%' 这个错误 Google 搜索和查看 SO 都没找到答案。

    回复 2最近活动 nim
  3. 从 APL 函数返回结果

    怎样才能让函数在执行结束后返回一个值? 例如我有这样的代码。 ROUTINE N ? N ⍴ 12 //它会生成 N 个从 1 到 12 的随机值 (N 是函数的参数)。 我只是想知道怎样拿到函数的结果,然后比如把这个结果传给另一个函数。 谢谢大家的…

    回复 2最近活动 apl