上一个功能输入参数正确存储

时间:2015-06-03 12:50:48

标签: clojure

我开始学习clojure以便原谅noob问题 我尝试实现以下功能

伪代码:

function(x y) {
  if (x != oldX)
    dosomething(y);
  oldX = x;
}

oldX是全局变量

我怎样才能正确地做到这种方式呢?

我写了一些东西,但这是否正确?

(defn rec [x y]  
  (if (not= x oldX)
    (println "y"))
  (def oldX x))

3 个答案:

答案 0 :(得分:5)

defs应该只是顶级。 (def oldX (atom nil))(reset! oldX x)更正确。

答案 1 :(得分:3)

Clojure是一种函数式编程语言。这是一种与其他流行的编程语言(如Python)不同的范例。你似乎没有想到功能; - )

Clojure-way不会在这种情况下使用变量。只需使用函数解决它,或者,如果确实有必要,请使用atomsref s,具体取决于您的需要。

可以在函数中修改atomref以存储旧结果 - 这可能是您正在寻找的解决方案。

但是对于大多数情况,存在一个更简单的解决方案,而不需要像oldX这样的变量 - 这就是功能语言的好处。

您的代码

(defn rec [x y]  
  (if (not= x oldX)
    (println "y"))
  (def oldX x))

正如@cgrand已经说过,def只能在第一级使用。

您使用if,但只定义true个案。如果您只检查,如果某个陈述为真,那么您可以使用when

最后一行在函数oldX的范围内定义了新的rec。这是一个 new 变量,而不是具有新值的旧变量,在活动命名空间中(感谢@ user1571406)。

答案 2 :(得分:0)

我认为你正在寻找的是这样的。我已经尝试将您的var名称保留为原始名称,因此更容易看出差异。

  1. 使用atom存储oldX
  2. 使用compare-and-set!确定您是否更改了原子
  3. 如果您更改了原子,请拨打(dosomething y)
  4. 注意:这有点像swap!,除了swap!返回交换的值,而不是您对swap!的调用是否改变了价值,所以在这里不太有用。

    这样的事情:

    (defn dosomething [y] 
      ;; does something, presumably with y...
      )
    
    (defonce x-atom (atom nil))
    
    (defn swap-x
      "swaps x-atom for new x, calls (dosomething ...) with y if successful"
      [x y]
      (let [oldX @x-atom] ; get the cur value of x
        (when (not= oldX x)
          (when (compare-and-set! x-atom oldX x)
            (dosomething y))
    

    如果compare-and-set!失败,则意味着其他一些线程已经修改了原子,因为你得到了它的值。如果你需要处理这种情况,答案会有所不同。您可以使用swap!loop+recur。如果您不熟悉,swap!有点像compare-and-set!,会在失败时重复出现。