命名空间映射命名空间上的多方法调度
Multimethod dispatch on namespaced map namespace
是否可以基于命名空间映射命名空间进行分派,即 #:<this-thing>{}
?没有像打印或检查键前缀这样的技巧?
我认为最后一个很老套,因为可以覆盖键前缀:
(:qux/bar #:qux{:bar :baz}); => :baz
(:foo/bar #:qux{:foo/bar :baz}); => :baz
(:qux/bar #:qux{:foo/bar :baz}); => nil
这是不可能的,因为这只是 writer
制作的地图的可视化表示。如果地图中的所有键都共享相同的命名空间,则您必须自己进行检查。最后一个示例也不会由作者生成 - 它只会在 all the keys share the same namespace.
时发出命名空间映射文字
一个映射可能包含来自某个命名空间的所有限定关键字键,或者它可能包含来自多个命名空间的非限定键或限定键的混合。这是一个从映射中的限定关键字键获取所有名称空间(作为关键字)集合的函数:
(defn key-namespaces
"Returns set of all namespaces of keys in m."
[m]
(->> (keys m)
(keep (comp keyword namespace))
(set)))
现在您可以在多方法上将其用作 dispatch-fn
:
(defmulti do-thing key-namespaces)
(defmethod do-thing #{:foo} [m] (prn m))
(do-thing #:foo{:bar 1})
;; #:foo{:bar 1}
(foo {:bar/bar 1})
;; no multimethod found exception
您可以在该集合中指定多个命名空间前缀,或者您可以根据您的用例使用不同的 dispatch-fn
。
是否可以基于命名空间映射命名空间进行分派,即 #:<this-thing>{}
?没有像打印或检查键前缀这样的技巧?
我认为最后一个很老套,因为可以覆盖键前缀:
(:qux/bar #:qux{:bar :baz}); => :baz
(:foo/bar #:qux{:foo/bar :baz}); => :baz
(:qux/bar #:qux{:foo/bar :baz}); => nil
这是不可能的,因为这只是 writer
制作的地图的可视化表示。如果地图中的所有键都共享相同的命名空间,则您必须自己进行检查。最后一个示例也不会由作者生成 - 它只会在 all the keys share the same namespace.
一个映射可能包含来自某个命名空间的所有限定关键字键,或者它可能包含来自多个命名空间的非限定键或限定键的混合。这是一个从映射中的限定关键字键获取所有名称空间(作为关键字)集合的函数:
(defn key-namespaces
"Returns set of all namespaces of keys in m."
[m]
(->> (keys m)
(keep (comp keyword namespace))
(set)))
现在您可以在多方法上将其用作 dispatch-fn
:
(defmulti do-thing key-namespaces)
(defmethod do-thing #{:foo} [m] (prn m))
(do-thing #:foo{:bar 1})
;; #:foo{:bar 1}
(foo {:bar/bar 1})
;; no multimethod found exception
您可以在该集合中指定多个命名空间前缀,或者您可以根据您的用例使用不同的 dispatch-fn
。