【问题标题】:How do you match against a defrecord's type in a case statement?您如何匹配 case 语句中的 defrecord 类型?
【发布时间】:2021-10-03 01:27:47
【问题描述】:

为什么case 在使用记录类型时不起作用?

(defrecord Thing [x])
=> myproject.core.Thing

(defn foo [x]
  (case (type x)
    Thing "Thing found!"
    "nope!"))
=> #'myproject.core/foo

(foo (Thing. 123))
=> "nope!"

为什么这不起作用?直接测试相等性似乎有效:

(= (type (Thing. 123)) Thing)
=> true

【问题讨论】:

    标签: clojure


    【解决方案1】:

    答案可以在case的文档字符串中找到:

    The test-constants are not evaluated. They must be compile-time
    literals, and need not be quoted. ... All manner of constant
    expressions are acceptable in case, including numbers, strings,
    symbols, keywords, and (Clojure) composites thereof.
    

    所以Thing 只是一个符号,而不是一个类/类型。您可以在此示例中看到这是正确的:

    dev=> (case (symbol "java.lang.Long")
     #_=>   java.lang.Long "long"
     #_=>   "short")
    "long"
    dev=> (case (class 1)
     #_=>   java.lang.Long "long"
     #_=>   "short")
    "short"
    dev=> 
    

    在第二种情况下,(class 1) 的计算结果为java.lang.Long——java.lang.Class 类型的对象——但正如我们从第一种情况中看到的那样,java.lang.Long 作为测试常数是clojure.lang.Symbol .

    【讨论】:

    • 尽管有文档,但在 ClojureScript 中,作为 case 的符号 可能 被评估,这取决于它们似乎指的是什么!因此,如果算法具有潜在的可移植性,出于一般目的,使用“cond”或协议或多方法比在“case”中使用符号作为标准更为谨慎。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-08-06
    • 1970-01-01
    • 2023-02-07
    • 1970-01-01
    • 2011-10-17
    • 2011-04-23
    • 1970-01-01
    相关资源
    最近更新 更多