0

是否可以基于命名空间映射命名空间进行调度,即#:<this-thing>{}?没有像打印或检查键前缀这样的黑客攻击?

我认为最后一个很hacky,因为可以覆盖键前缀:

(:qux/bar #:qux{:bar :baz}); => :baz
(:foo/bar #:qux{:foo/bar :baz}); => :baz
(:qux/bar #:qux{:foo/bar :baz}); => nil
4

2 回答 2

3

映射可能包含来自某个命名空间的所有限定关键字键,或者它可能包含来自多个命名空间的非限定键或限定键的混合。这是一个从映射中的限定关键字键中获取所有名称空间(作为关键字)的函数:

(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根据您的用例使用不同的名称空间前缀。

于 2018-04-30T12:26:46.220 回答
1

这是不可能的,因为这只是由writer. 如果地图中的所有键共享相同的命名空间,您必须自己进行检查。最后一个示例也不会由编写器生成 - 只有当所有键共享相同的命名空间时,它才会发出命名空间映射文字。

于 2018-04-30T12:26:11.713 回答