1

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)

誰か知っていますか?どうもありがとう。

4

1 に答える 1

3

実行時に検証のオンとオフを切り替えることができるため、レコードは関数に渡すまで実際にはチェックされません。

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

long魔法の働きについて。これは、プリミティブによる特別な clojure の動作です。

フィールドは型ヒントを持つことができ、プリミティブにすることができます

  • 現在、非プリミティブ型の型ヒントは、フィールド型やコンストラクター引数を制約するために使用されませんが、クラス メソッドでの使用を最適化するために使用されることに注意してください。

  • フィールド型とコンストラクタ引数の制約が計画されています

(s/defrecord PrimitveRec [foo :- long])
(s/defrecord NonPrimitveRec [foo :- String])


(.? NonPrimitveRec :field #"foo" :type)
;=> (java.lang.Object)
(.? PrimitveRec :field #"foo" :type)
;=> (long)

ヴィンヤサ.?出身です

于 2015-11-25T12:51:49.477 に答える