The case
医生说
与 cond 和 condp 不同,case 执行常量时间调度...所有常量方式
表达式是可以接受的情况下。
我想从中受益case
的常量时间调度以匹配 Java 枚举。爪哇的switch
语句适用于枚举,但在 Clojure 中执行以下操作:
(defn foo [x]
(case x
java.util.concurrent.TimeUnit/MILLISECONDS "yes!"))
(foo java.util.concurrent.TimeUnit/MILLISECONDS)
结果是:IllegalArgumentException No matching clause: MILLISECONDS
是否不支持枚举case
?难道我做错了什么?我必须求助于cond
或者有更好的解决方案吗?
这里的问题是case
的测试常量,如文档中所述,“必须是编译时的literals”。所以,与其解决java.util.concurrent.TimeUnit/MILLISECONDS
, 文字符号'java.util.concurrent.TimeUnit/MILLISECONDS
正在接受测试。
(foo java.util.concurrent.TimeUnit/MILLISECONDS) ; IllegalArgumentException
(foo 'java.util.concurrent.TimeUnit/MILLISECONDS) ; yes!
相反,解决方案是在.ordinal
of the Enum
实例,这是Java本身在编译时所做的事情switch
关于枚举的语句:
(defn foo [x]
(case (.ordinal x)
2 "yes!"))
您可以将此模式包装在宏中,该宏会为您正确计算大小写序数:
(defmacro case-enum
"Like `case`, but explicitly dispatch on Java enum ordinals."
[e & clauses]
(letfn [(enum-ordinal [e] `(let [^Enum e# ~e] (.ordinal e#)))]
`(case ~(enum-ordinal e)
~@(concat
(mapcat (fn [[test result]]
[(eval (enum-ordinal test)) result])
(partition 2 clauses))
(when (odd? (count clauses))
(list (last clauses)))))))
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)