4

在评估这个超级简单的 core.match 表达式时,我得到:

(match [(class "3.14")]
       [Integer] "Integer"
       [Double] "Doubler")
; => "Integer"

这怎么可能是正确的,我是否缺少关于 core.match 的一些基本内容?在这个表格上做一个 macroexpand-1 给我:

=> (clojure.core/let [ocr-2751 (class "3.14")] (clojure.core/let [Integer ocr-2751] "Integer"))

任何指针表示赞赏。

4

2 回答 2

8

就像@Arthur 所说,通常core.match会将值绑定到符号。但是,显然,它首先尝试与 locals 匹配。谁知道?

无论如何,在匹配之前将类绑定为本地人,let你很高兴:

(let [Integer java.lang.Integer
      String  java.lang.String]
  (match [(class "3.14")]
         [Integer] "Integer"
         [String] "String"))
于 2014-08-09T04:02:21.793 回答
7

core.match 允许您为 match 子句中的一个值命名,如下所示(来自示例

(let [x 1 y 2]
  (match [x y]
    [1 b] b
    [a 2] a
    :else nil))

在此示例中,如果第一个匹配值是 one,那么在用于生成结果的表达式中,第二个值将可以在 name 下访问b

因为 match 子句中的任何符号都被解释为将相应值绑定到该名称的指令,所以在您的情况下,名称Integer被绑定到该值java.lang.String

user> (match [(class "3.14")]
             [Integer] Integer
             [Double] "Doubler")
java.lang.String

user> (match [(class "3.14")]
             [name-to-bind] name-to-bind
             [Double] "Doubler")
java.lang.String

从文档中不清楚是否有一种方法可以使用 core.match 来评估 match 子句而不是绑定到它。可以通过匹配一个字符串来解决这个问题,尽管它失去了一些优雅:

user> (match [(str (class (int 3)))]
             ["class java.lang.Integer"] "Integer"
             ["class java.lang.String"] "String"
             ["class java.lang.Double"] "Double")
"Integer"
user> (match [(str (class "3.14"))]
             ["class java.lang.Integer"] "Integer"
             ["class java.lang.String"] "String"
             ["class java.lang.Double"] "Double")
"String"
user> (match [(str (class 3.14))]
             ["class java.lang.Integer"] "Integer"
             ["class java.lang.String"] "String"
             ["class java.lang.Double"] "Double")
"Double"
于 2014-08-07T18:12:25.433 回答