Clojure:此类型不支持:布尔"

PIN*_*INK 1 clojure clojure-java-interop

我正试图在clojure中实现餐饮哲学家的例子.由于某些原因,我的程序总是死于一个例外

"java.lang.UnsupportedOperationException:此类型不支持:布尔"

我无法理解这个错误消息,因为我已经尝试从列表中获取与第n个完美匹配的布尔值

我猜错误发生在函数philosopher-threadif语句

控制台打印:

  • 3在思考
  • 1正在思考
  • 4在思考
  • 0在想
  • 2在思考
  • 睡觉后0
  • 思考后0
  • 0交换
  • 0正在吃
  • 睡了3后
  • 思考后3

码:

(ns dining-philosphers.core
  (:gen-class))

(defn think [n] 
  (println (str n " is thinking"))
  (Thread/sleep (rand 1000))
  (println (str n " after sleep"))
)

(defn eat [n] 
  (println (str n " is eating"))
  (Thread/sleep (rand 1000))
)

(def isEating (atom '(false false false false false)))


(defn philosopher-thread [n] 
  (Thread. #( 
    (while true (do  
      (think n) 
      (println (str n " after think"))
      (if (or  (nth @isEating (mod (- n 1) 5))  (nth @isEating  (mod (+ n 1) 5)))
        (println "is waiting for neighbour")
        (
          do 
          (println (str n " swap"))
          (swap! isEating (fn [l] assoc l n true)) 
          (eat n)
          (swap! isEating (fn [l] assoc l n true))
        )
      )
     )
    ) 
  )

  )
)

(defn -main [& args] 
  (let [threads (map philosopher-thread (range 5))] 
    (doseq [thread threads] (.start thread))
    (doseq [thread threads] (.join thread))))
Run Code Online (Sandbox Code Playgroud)

Ale*_*lex 5

你在这里错过了一些parens:

(swap! isEating (fn [l] assoc l n true)) 
Run Code Online (Sandbox Code Playgroud)

应该

(swap! isEating (fn [l] (assoc l n true))) 
Run Code Online (Sandbox Code Playgroud)

第一将评估assoc,l,ntrue在顺序,并返回最后一个表达式的值(true)

还有一个问题,就是你无法assoc进入清单.我建议使用矢量代替:

(def isEating (atom [false false false false false]))
Run Code Online (Sandbox Code Playgroud)