5
你能用例子來解釋retag
參數如何影響multi-spec
創建?我發現multi-spec
文檔很難消化。s/multi-spec中的retag參數是什麼意思?
你能用例子來解釋retag
參數如何影響multi-spec
創建?我發現multi-spec
文檔很難消化。s/multi-spec中的retag參數是什麼意思?
從文檔字符串:
重新標記被生成期間使用 匹配的標籤重新標記生成的值。 retag可以是關鍵字,關鍵字是 調度標籤將被關聯,或者生成值fn和 調度標籤,該標籤應該返回適當的重新標記的值。
如果retag
是一個關鍵字(如在spec guide example),multi-spec
內部創建其在發電機執行功能中使用的功能here。例如,這兩個多規格的聲明在功能上等同:
(s/def :event/event (s/multi-spec event-type :event/type))
(s/def :event/event (s/multi-spec event-type
(fn [genv tag]
(assoc genv :event/type tag))))
傳遞一個retag
功能似乎並不像給導遊的例子一個非常有用的選項,但使用multi-spec
用於非時是比較有用地圖。例如,如果您想要使用multi-spec
和s/cat
符合規範函數參數:
(defmulti foo first)
(defmethod foo :so/one [_]
(s/cat :typ #{:so/one} :num number?))
(defmethod foo :so/range [_]
(s/cat :typ #{:so/range} :lo number? :hi number?))
foo
需要兩個或三個參數,根據第一ARG。如果我們試圖multi-spec
這個天真地使用s/cat
關鍵字/標籤,它不會工作:
(s/def :so/foo (s/multi-spec foo :typ))
(sgen/sample (s/gen :so/foo))
;; ClassCastException clojure.lang.LazySeq cannot be cast to clojure.lang.Associative
這是能夠傳遞一個retag
函數,其中很有用:
(s/def :so/foo (s/multi-spec foo (fn [genv _tag] genv)))
(sgen/sample (s/gen :so/foo))
;=>
;((:so/one -0.5)
; (:so/one -0.5)
; (:so/range -1 -2.0)
; (:so/one -1)
; (:so/one 2.0)
; (:so/range 1.875 -4)
; (:so/one -1)
; (:so/one 2.0)
; (:so/range 0 3)
; (:so/one 0.8125))
感謝您的偉大解釋和例子! – OlegTheCat