在 `case` 中使用通道

Using channel in `case`

(let [a (clojure.core.async/chan)]
  (case a
    a :foo
    :bar))
#=> :bar

我希望 :foo 在这里。我做错了什么?

另一方面 (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

The docs for case有答案

The test-constants are not evaluated. They must be compile-time literals, and need not be quoted.

正确的解决方法是使用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

Case 在子句的左侧使用 未评估的测试常量。纯符号,如 chan1 将仅匹配具有相同名称的符号,而不匹配具有该名称的本地绑定的值; chan1 将匹配 'chan1