Clojure,redeclear 变量导致警告“已经指代”

Opt*_*ime 1 clojure

我今天开始学习 Clojure,但遇到了一个用 cleaver Googeling 无法解决的问题。

我有一个简单的脚本,我想在满足条件时增加计数器。我了解到 Clojure 中的变量是不可变的,增加它的方法是重新清除它,但这会引发警告。

(defn main[]
    (def num 0)
    (if [...]
        (def num (+ num 1))
    )
)
Run Code Online (Sandbox Code Playgroud)

但是,这会引发以下警告:

WARNING: num already refers to: #'clojure.core/num in namespace: user, being replaced by: #'user/num
Run Code Online (Sandbox Code Playgroud)

noi*_*ith 6

这里有两个问题:

一,您正在隐藏 clojure.core 中的一个函数。这会收到警告,因为它可能导致意外行为。如果您知道不会使用clojure.core/num,则可以在命名空间声明中包含以下内容:

(ns my.ns
  (:refer-clojure :exclude [num])
  ....)
Run Code Online (Sandbox Code Playgroud)

下一个问题:def不是用于创建本地值。将 def 用作顶级形式以外的任何内容几乎总是一个错误,并且对此的任何例外都应该需要非常明确的理由。它只能创建全局可变var的。使用let针对特定于一个范围,像一个函数里面绑定。

(defn -main
  [& args]
  (let [num 0
        num (if ... num (inc num))]
    ...))
Run Code Online (Sandbox Code Playgroud)

在这里, num 没有改变,也没有创建为 global var,但它是一个本地绑定,被第二个绑定遮蔽。