2024 Clojure 状态调查! 中分享您的想法。

欢迎!请参阅 关于页面 了解更多关于如何操作的信息。

0
集合

clojure.set/intersection 似乎使用了向量的索引作为值。如果在其中一个参数中意外传递了向量,这将导致非常奇怪的行行为。

`
ti.repl-init=> (clojure.set/intersection #{0 1} [2 2 2 2 2])

{0 1}

ti.repl-init=> (clojure.set/intersection [2 2 2 2] #{0 1})

{0 1}

ti.repl-init=> (clojure.set/intersection [0 1] [2 2 2 2])
[0 1]
ti.repl-init=> (clojure.set/intersection [2 2 2 2] [2 2 2 2])
[2 2 2 2]
ti.repl-init=> (clojure.set/intersection [3 3 3 ] [2 2 2 2])
[3 3 3]
ti.repl-init=> (clojure.set/intersection [55] [2 2 2 2])

ClassCastException clojure.lang.PersistentVector 不能被转换到 clojure.lang.IPersistentSet clojure.core/disj (core.clj:1476)
`

如果任何参数是列表,你会得到一个 ClassCastException,这可能没有我们希望的那样明确。

`
ti.repl-init=> (clojure.set/intersection #{0 1} (list 2 2 2 2))

IllegalArgumentException 不支持在类型 clojure.lang.PersistentList 上使用 contains? clojure.lang.RT.contains (RT.java:814)
`

如果所有参数都是列表,也会发生相同的情况

4 答案

0
_评论来自:ashtonkemerling_

更多奇怪的副作用。


ti.repl-init=> (clojure.set/intersection #{:foo} {:foo 1})
#{:foo}
ti.repl-init=> (clojure.set/intersection #{:foo} {})
{}
ti.repl-init=> (clojure.set/intersection #{:foo} [:foo])
#{}
ti.repl-init=> (clojure.set/intersection [:foo] [:foo])

ClassCastException clojure.lang.PersistentVector 不能被转换到 clojure.lang.IPersistentSet  clojure.core/disj (core.clj:1476)
ti.repl-init=> (clojure.set/intersection [0] [:foo])
[0]
0

评论来自:alexmiller

请参阅 CLJ-1953 的评论。

0
by

评论者:jafingerhut

如果您需要一个现成的、与 clojure.set 函数行为完全相同的替换方案,但它们会为您提供的参数执行运行时类型检查,并在类型不正确时抛出异常(例如,对于并集、交集、差集、子集?和超集?不是集合),请考虑使用 fungible 库:https://github.com/jafingerhut/funjible

0
by
参考资料:https://clojure.atlassian.net/browse/CLJ-1954(由 alex+import 报告)
...