【问题标题】:Clojure prismatic/schema defrecord no enum runtime validation?Clojure prismatic/schema defrecord 没有枚举运行时验证?
【发布时间】:2016-02-27 22:53:18
【问题描述】:

使用 prismatic/schema 时,defrecord 上的枚举验证不起作用,如下所示:

(s/defrecord Action [type :- (s/enum :a :b)])
#'user/strict-map->Action
user> (Action. "3")            ; this should fail
#user.Action{:type "3"}
user> (Action. 1)              ; this should fail
#user.Action{:type 1}
user> (Action. "abc")          ; this should fail
#user.Action{:type "abc"}

但是,当我将 enum 更改为 long 时,它会按预期工作:

(s/defrecord ThisWorks [type :- long])
#'user/strict-map->ThisWorks
user> (ThisWorks. 3)
#user.ThisWorks{:type 3}
user> (ThisWorks. "abc")
ClassCastException java.lang.String cannot be cast to java.lang.Number  user/eval11888 (form-init4803894880546699153.clj:1)

有人知道吗?非常感谢。

【问题讨论】:

    标签: clojure clojurescript plumatic-schema


    【解决方案1】:

    因为您可以switch on and off validation during runtime 您的记录在您将它们传递给函数之前不会被实际检查:

    (s/defrecord Action [type :- (s/enum :a :b)])
    (s/defn process-action [x :- Action])
    (process-action (Action. "3")) ;; => Exception
    

    关于long 神奇地工作。这只是special clojure behavior due to primitives:

    字段可以有类型提示,也可以是原始的

    • 请注意,目前一个 非原始类型的类型提示不会用于约束 字段类型也不是构造函数arg,而是会用来优化它的 在类方法中使用

    • 约束字段类型和构造函数 arg 计划中

    (s/defrecord PrimitveRec [foo :- long])
    (s/defrecord NonPrimitveRec [foo :- String])
    
    
    (.? NonPrimitveRec :field #"foo" :type)
    ;=> (java.lang.Object)
    (.? PrimitveRec :field #"foo" :type)
    ;=> (long)
    

    .? 来自Vinyasa。

    【讨论】:

      猜你喜欢
      • 2014-10-24
      • 1970-01-01
      • 2023-02-06
      • 1970-01-01
      • 2014-11-12
      • 1970-01-01
      • 2014-10-31
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多