我今天开始学习 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)
这里有两个问题:
一,您正在隐藏 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,但它是一个本地绑定,被第二个绑定遮蔽。