Clojure prismatic/schema defrecord 没有枚举运行时验证?
Clojure prismatic/schema defrecord no enum runtime validation?
使用 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)
有人知道吗?非常感谢。
因为您可以 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:
fields can have type hints, and can be primitive
note that currently a
type hint of a non-primitive type will not be used to constrain the
field type nor the constructor arg, but will be used to optimize its
use in the class methods
constraining the field type and constructor
arg is planned
(s/defrecord PrimitveRec [foo :- long])
(s/defrecord NonPrimitveRec [foo :- String])
(.? NonPrimitveRec :field #"foo" :type)
;=> (java.lang.Object)
(.? PrimitveRec :field #"foo" :type)
;=> (long)
其中 .?
来自 Vinyasa.
使用 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)
有人知道吗?非常感谢。
因为您可以 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:
fields can have type hints, and can be primitive
note that currently a type hint of a non-primitive type will not be used to constrain the field type nor the constructor arg, but will be used to optimize its use in the class methods
constraining the field type and constructor arg is planned
(s/defrecord PrimitveRec [foo :- long])
(s/defrecord NonPrimitveRec [foo :- String])
(.? NonPrimitveRec :field #"foo" :type)
;=> (java.lang.Object)
(.? PrimitveRec :field #"foo" :type)
;=> (long)
其中 .?
来自 Vinyasa.