避免覆盖变量名称

Ham*_*aya 5 clojure

在我正在处理的特定命名空间上,我开始耗尽函数名称.如果我重用一个已绑定到同一命名空间中的函数的符号,是否有办法获得类似于我从另一个命名空间覆盖符号的警告?

Mic*_*zyk 4

如果这已经是一个足够的问题,您愿意替换一个(一组)核心宏,您可以尝试以下方法:

(ns huge.core
  (:refer-clojure :exclude [defn]))

(defmacro defn [name & defn-tail]
  (assert (nil? (resolve name))
          (str "Attempting to redefine already defined Var "
               "#'" (.name *ns*) "/" name))
  `(clojure.core/defn ~name ~@defn-tail))
Run Code Online (Sandbox Code Playgroud)

那么任何重新定义现有 Var 的尝试defn都会失败:

user=> (defn foo [] :foo)
#'user/foo
user=> (defn foo [] :bar)
AssertionError Assert failed: Attempting to redefine already defined Var #'user/foo
(nil? (resolve name))  user/defn (NO_SOURCE_FILE:2)
Run Code Online (Sandbox Code Playgroud)

您可以类似地替换defmacro; 在这种情况下,您必须clojure.core/defmacro在定义自己的变体时调用。

Plain, unadorneddef是一种特殊形式,并受到编译器的神奇处理,因此您仍然可以用它覆盖现有的 Var。如果您也想防止该侧翼上的名称冲突,您可以使用类似的自定义断言切换到类似的东西defvar(曾经在 中可用)。clojure.contrib.def