【问题标题】:Why do other threads not see my ref update?为什么其他线程看不到我的参考更新?
【发布时间】:2011-11-11 21:25:45
【问题描述】:

我正在使用 Swing 在 Clojure 中开发一款游戏。我有一个 KeyListener 来处理控件,但它没有更新参考。

(def move (ref :drop))

(defn get-move 
  [block state x y moves]
  (do (println @move)
      (if (check-move @move x y block state) @move
        :nothing)))



(defn listener
  [keyevent]
  (let [c (.getKeyChar keyevent)]
   (do (println c)
      (cond (= c "j") (dosync (ref-set move :left))
            (= c "l") (dosync (ref-set move :right))
            (= c "i") (dosync (ref-set move :rotate))
            (= c "k") (dosync (ref-set move :drop))))))



(defn make-keylistener
  []
 (proxy [KeyAdapter] []
  (keyPressed [event]
            (listener event))))

现在,这个想法是更新 gui 的主要函数调用 get-move。它检查移动参考在游戏中是否有效,如果是则返回它。侦听器附加到 JPanel 并根据按键更改 ref。侦听器工作正常 - 每当按下按钮时,它都会打印出键字符。我只能假设它正在改变参考。但是,get-move 总是返回相同的值——它永远不会看到 @move 发生变化。我觉得我误解了 Clojure 中关于并发和状态的一些基本内容。我做错了什么,有没有更实用的方法来处理这个问题?

谢谢!

编辑:如果我使用原子,也会出现同样的问题。

【问题讨论】:

    标签: concurrency clojure


    【解决方案1】:

    这不是并发问题。 .getKeyChar 返回一个字符,我将其与字符串进行比较。将条件重写为 (= (str c) "j") 使其工作。

    【讨论】:

    • 因此,如果您要与 char 进行比较,您可以简单地写:(= c \j)
    • \表示一个字符?很高兴知道,我还没有遇到过。
    猜你喜欢
    • 2012-07-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多