clojure - 使变量常量用于 Clojure 中的 case 语句

标签 clojure

在 Clojure 中,有没有办法使 var 常量可以在 case 语句中使用?

例如

(def a 1)
(def b 2)

(let [x 1]
  (case x
    a :1
    b :2
    :none))
=> :none

我知道我可以使用 condcondp 之类的东西来解决这个问题,但如果我可以定义不需要进一步评估的东西,那就太好了,所以我可以使用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/

相关文章:

postgresql - 尝试使用 jdbc 从 clojure 连接到 postgresql 时密码身份验证失败

Clojure 宏问题

collections - pop 是否抛出异常?

java - 现实世界中的 Clojure 和 Java 互操作

session - 在 clojure-ring 中清除 session (注销用户)

emacs - 在 Emacs 中安装 Clojure 时,我收到很多警告和错误

Clojure:难以成功地将协议(protocol)应用于 2 种类型

authentication - 如何让 Swagger UI 让我提供身份验证 header ?

主线程中的 Clojure 异常

clojure - 客户端的环中间件?