为什么运行println时y = 0?

时间:2015-06-13 14:50:42

标签: clojure

我怎么跑

  (def y 0)
  (doseq [x (range 1000)] (if (or (= (mod x 3) 0) (= (mod x 5) 0)) (+ y x)))
  (println y)

它打印0,好像没有添加,但

(doseq [x (range 1000)] (if (or (= (mod x 3) 0) (= (mod x 5) 0)) (println x)))

会打印出符合条件的所有相应数字吗?

2 个答案:

答案 0 :(得分:3)

在clojure中,值是不可变的。 y是,并且永远都是0。 (+ y 1)为1,始终为1. (+ y 1)不会更改y的值,它只是评估为向不可变值y添加1的结果。

试试这个:

(println 
  (reduce 
    (fn [y x]
      (if (or (= (mod x 3) 0) 
              (= (mod x 5) 0)) 
        (+ y x) y))
  0 (range 1000)))

在这里,我们通过缩小相关范围来逐步建立y。如果我们符合您的条件,我们会添加下一个值(x)。如果我们不符合您的条件,我们只返回y。

查找reduce功能。

注意:有我的错别字,我在手机上写了这个

答案 1 :(得分:2)

与所有其他主流语言一样,Clojure中的+没有副作用,也没有改变其输入。 doseq中没有可能改变y的价值的逻辑。

在第二个示例中,println中的doseq会看到x的临时本地值,这有时会导致打印。