2017-03-06 21 views
2
(let [a (clojure.core.async/chan)] 
    (case a 
    a :foo 
    :bar)) 
#=> :bar 

我期望:foo這裏。我究竟做錯了什麼?在'case'中使用頻道

另一方面,(condp = chan ...)完成這項工作。

PS:

基本上我嘗試做以下事情:

(require '[clojure.core.async :as a]) 
(let [chan1 (a/chan 10) 
     chan2 (a/chan 10)] 
    (a/>!! chan1 true) 
    (let [[v c] (a/alts!! [chan1 chan2])] 
    (case c 
     chan1 :chan1 
     chan2 :chan2 
     :niether))) 
#=> :neither 
+0

永遠不要讀取源代碼。 ;)只需閱讀文檔(見下文)。 –

+0

@AlanThompson刪除。我試圖在公交停車期間想到一些事情。顯然,這並沒有奏效。我喜歡閱讀核心來源!那裏有許多有趣的東西,雖然它很多都很模糊。 – Carcigenicate

回答

4

The docs for case有答案

試驗常數不被評估。它們必須是編譯時文字,不需要引用。

正確的解決辦法是使用cond

(let [chan1 (ca/chan 10) 
     chan2 (ca/chan 10)] 
    (ca/>!! chan1 true) 
    (let [[v c] (ca/alts!! [chan1 chan2])] 
     (spyx (cond 
       (= c chan1) :chan1 
       (= c chan2) :chan2 
       :else :neither)))) 

;=> :chan1 
+0

'(condp = c'更簡潔,我想 – fl00r

1

案例使用未計算的測試常數在子句的左手側。普通符號,如chan1這裏將僅匹配具有相同名稱的符號,而不匹配具有該名稱的本地綁定的值; chan1將匹配'chan1