在 Clojure 中,有没有办法使 var 常量可以在 case
语句中使用?
例如
(def a 1)
(def b 2)
(let [x 1]
(case x
a :1
b :2
:none))
=> :none
我知道我可以使用 cond
或 condp
之类的东西来解决这个问题,但如果我可以定义不需要进一步评估的东西,那就太好了,所以我可以使用case
。
最佳答案
Related and answer stolen from it:
正如文档字符串告诉您的那样:不,您不能这样做。您可以使用Chas Emericks macro并执行此操作:
(defmacro case+
"Same as case, but evaluates dispatch values, needed for referring to
class and def'ed constants as well as java.util.Enum instances."
[value & clauses]
(let [clauses (partition 2 2 nil clauses)
default (when (-> clauses last count (== 1))
(last clauses))
clauses (if default (drop-last clauses) clauses)
eval-dispatch (fn [d]
(if (list? d)
(map eval d)
(eval d)))]
`(case ~value
~@(concat (->> clauses
(map #(-> % first eval-dispatch (list (second %))))
(mapcat identity))
default))))
因此:
(def ^:const a 1)
(def ^:const b 2)
(let [x 1]
(case+ x
a :1
b :2
:none))
=> :1
另一种选择(这很好,因为它更强大)是使用 core.match
的功能。尽管您只能匹配本地绑定(bind):
(let [x 2
a a
b b]
(match x
a :1
b :2
:none))
=> :2
关于clojure - 使变量常量用于 Clojure 中的 case 语句,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32300269/