我会逐步回答这个问题。让我们从=等价谓词开始。 =谓词用于检查两个数字是否相等。如果你提供其他任何东西,但一个数字,那么它会引发一个错误:
(= 2 3) => #f
(= 2.5 2.5) => #t
(= '() '()) => error
等式?谓词用于检查其两个参数是否表示内存中的相同对象。例如:
(define x '(2 3))
(define y '(2 3))
(eq? x y) => #f
(define y x)
(eq? x y) => #t
注意,在内存中只有一个空列表()(实际上,空列表不存在于内存中,但是指向内存位置0的指针被认为是空列表)。因此,当比较空列表eq?将总是返回#t(因为它们表示内存中的相同对象):
(define x '())
(define y '())
(eq? x y) => #t
现在取决于实现eq?可能或可能不返回原始值(如数字,字符串等)的#t。例如:
(eq? 2 2) => depends upon the implementation
(eq? "a" "a") => depends upon the implementation
这是eqv?谓词进入图片。等式是完全相同的eq?谓词,除了它将始终返回相同的原始值的#t。例如:
(eqv? 2 2) => #t
(eqv? "a" "a") => #t
因此eqv?是eq?的超集。在大多数情况下,你应该使用eqv?而不是eq。
最后我们来到平等?谓词。平等?谓词与eqv完全相同?除了它也可以用于测试两个列表,向量等是否具有满足等式1的对应元素。谓词。例如:
(define x '(2 3))
(define y '(2 3))
(equal? x y) => #t
(eqv? x y) => #f
一般来说:
>当你想测试两个数字是否相等时,使用=谓词。>使用eqv?当您希望测试两个非数字值是否相等时,使用谓词。>使用等号?谓词,当你想测试两个列表,向量等是否是等价的。>不要使用eq?谓词,除非你知道你在做什么。