更改Clojure中全局变量的值

更改Clojure中全局变量的值,clojure,Clojure,我在Clojure是个彻头彻尾的新手,我遇到了一个问题,我甚至不确定是否可以在结束时解决 因此,问题如下。我已经实现了一个函数,可以从一个区间(到一个极限)计算素数 然后在返回时,将条目添加到这个变量中。这在Clojure中是可能的吗?如果是,如何实现?我已经尝试过使用swap和原子,或设置!但是在任何情况下都无法在这里工作。首先,我强烈建议您阅读clojure代码约定 让我向您展示代码的一些改进 1) 应用clojure命名约定 然后从(+变量1)切换到(inc变量)(与dec的优化相同) 另

我在Clojure是个彻头彻尾的新手,我遇到了一个问题,我甚至不确定是否可以在结束时解决

因此,问题如下。我已经实现了一个函数,可以从一个区间(到一个极限)计算素数


然后在返回时,将条目添加到这个变量中。这在Clojure中是可能的吗?如果是,如何实现?我已经尝试过使用
swap和原子,或设置!但是在任何情况下都无法在这里工作。

首先,我强烈建议您阅读clojure代码约定

让我向您展示代码的一些改进

1) 应用clojure命名约定

然后从
(+变量1)
切换到
(inc变量)
(与
dec的优化相同)

另外,
(=FIND\u MORE\u PRIMES false)
可以简单地替换为
FIND MORE PRIMES?

最后,条件
(=0 smthng)
可以用更惯用的风格编写
(零?smthng)

现在,您的代码看起来更具可读性:

(defn gather-primes-in-range [range-start range-end target-number prime-list]
  (if (or (zero? target-number) (> range-start range-end) need-more-primes?)
    prime-list
    (do
      (if (is-prime? range-start)
        (gather-primes-in-range (inc range-start) range-end (dec target-number) (conj prime-list range-start))
        (gather-primes-in-range (inc range-start) range-end target-number prime-list)))))
2) 现在我们应该删除冗余的
do
调用,因为它只包装了一个函数调用

最后一个技巧是通过交换整个
范围内的聚集素数来应用尾部递归(*)
调用
recur

(defn gather-primes-in-range 
  [range-start range-end target-number prime-list]
    (if (or (zero? target-number) (> range-start range-end) need-more-primes?)
      prime-list
      (if (is-prime? range-start)
        (recur (inc range-start) range-end (dec target-number) (conj prime-list range-start))
        (recur (inc range-start) range-end target-number prime-list))))
现在是回答你问题的时候了。你不会从这种方法中受益

(def PRIMES_FOUND_SO_FAR #{})
因为您没有机会更改此设置。您唯一能处理的就是从该数据结构创建一些新的不可变数据结构

正如@georgek所提到的,您可以简单地在这个特殊情况下使用

(def PRIMES_FOUND_SO_FAR (atom #{}))
向原子添加新素数:

(swap! PRIMES_FOUND_SO_FAR conj prime-number)
Deref atom用于提取值:

@PRIMES_FOUND_SO_FAR ;; or (deref PRIMES_FOUND_SO_FAR)
-> #{2 3 5 7 11}
无论如何,您的代码是有点必要的,但您应该始终记住clojure是一种具有不可变数据结构、函数作为参数等的函数式语言。使用全局变量根本不是一个好主意。顺便说一句,clojure风格的函数应该是这样的:

(defn gather-primes-in-range [start end target-number]
  (take target-number (filter is-prime? (range start end))))

对于那些花了太多时间搜索如何在clojure中修改全局(根)变量的人,以下是解决方案:

(def user-remote-browser "anonymous")
您可以在任何地方修改它,但名称相同,使用:

(alter-var-root #'user-remote-browser (constantly name))
alter var root使用函数修改变量,
不断创建一个常量函数,在这里返回字符串名

您是说您没有尝试使用atom执行此操作吗?谢谢,这很有帮助。一个简单的问题,我如何改变一个布尔原子,使其具有一个新的值(如果可能的话)?我想用它来设置全局标志need-more-primes。定义变量:
(def need?(atom false))
要更改它,请使用
(reset!need?true)
。获取atom的值-
@need?
。请不要再问了,这有可能吗?Clojure的魔力远超你的想象。:)
(def user-remote-browser "anonymous")
(alter-var-root #'user-remote-browser (constantly name))