2024 Clojure现状调查!中分享您的看法。

欢迎!请查阅关于页面以了解更多关于此功能的信息。

0
Clojure

我有两个序列'a'和'b'。它们长度相同且对应元素通过'='比较相等。但将这两个序列传递给'='时,结果是false

(doseq [[x y] (zip-colls a b)]
  (println (= x y)))
true
true
true
true

(count a)
4
(count b)
4

(= a b)
false

这与Clojure的等价规则相矛盾

Clojure的'='在调用两个集合时为true,如果

两个参数都是顺序的(序列、列表、向量、队列或实现java.util.List的Java集合),并且具有相同顺序的'='元素。

我在比较这个类的两个实例:https://github.com/fctorial/parse_struct/blob/master/src/clojure/lang/ROVec.java

1 答案

0
 
最佳答案

这就是你的问题所在

如果对象实现了equiv,它将通过《=》被选中。

对于所有其他类型
两个参数是与使用deftype定义的相同类型。
调用类型equiv方法,其返回值将成为《= x y》的值。
对于其他类型,Java的x.equals(y)为true。

我敢打赌,如果你比较它们的seq coercion上的=,你会发现序列是等于的...

(deftype wrapper [xs] 
   clojure.lang.IPersistentCollection 
   (equiv [this that] false) 
   clojure.lang.Seqable 
   (seq [this] (seq xs)))

user=> (let [xs (wrapper. [1 2 3]) 
             ys (wrapper. [1 2 3])] 
         [(= xs ys) (= (seq xs) (seq ys))])
[false true]
这很尴尬。我已经在这份文件中搜索过'equals'了。
大多数Clojure集合都将实现equiv和equals来支持Clojure持久化集合的等价性和Java互操作性。它们还实现了hasheq以进行自定义哈希。它们为这些还提供了专门的实用函数(hash-unordered-collection和hash-ordered-collection),这些函数使用murmur3进行辞令哈希,与Clojure现有集合保持一致。关于等价性有很多东西可能很棘手。
更详细的信息,请参阅https://clojure.org/guides/equality
...