Scheme中的eq?、eqv?、equal?和=有什么区别? [英] What is the difference between eq?, eqv?, equal?, and = in Scheme?

查看:18
本文介绍了Scheme中的eq?、eqv?、equal?和=有什么区别?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想知道 Scheme 中的这些操作之间有什么区别.我在 Stack Overflow 上看到过类似的问题,但它们是关于 Lisp 的,其中三个运算符之间没有比较.

I wonder what the difference is between those operations in Scheme. I have seen similar questions in Stack Overflow but they are about Lisp, and there is not a comparison between three of those operators.

我在 Scheme 中编写不同类型的命令,得到以下输出:

I am writing the different types of commands in Scheme, and I get the following outputs:

(eq? 5 5) -->#t
(eq? 2.5 2.5) -->#f
(equal? 2.5 2.5) --> #t
(= 2.5 2.5) --> #t

为什么会这样?

推荐答案

我会逐步回答这个问题.让我们从 = 等价谓词开始.= 谓词用于检查两个数字是否相等.如果您提供除数字以外的任何其他内容,则会引发错误:

I'll answer this question incrementally. Let's start with the = equivalence predicate. The = predicate is used to check whether two numbers are equal. If you supply it anything else but a number then it will raise an error:

(= 2 3)     => #f
(= 2.5 2.5) => #t
(= '() '()) => error

eq? 谓词用于检查它的两个参数是否代表内存中的同一个对象.例如:

The eq? predicate is used to check whether its two parameters respresent the same object in memory. For example:

(define x '(2 3))
(define y '(2 3))
(eq? x y)         => #f
(define y x)
(eq? x y)         => #t

但是请注意内存中只有一个空列表'()(实际上内存中不存在空列表,而是指向内存位置0的指针被视为空列表).因此,当比较空列表时,eq? 将始终返回 #t(因为它们代表内存中的相同对象):

Note however that there's only one empty list '() in memory (actually the empty list doesn't exist in memory, but a pointer to the memory location 0 is considered as the empty list). Hence when comparing empty lists eq? will always return #t (because they represent the same object in memory):

(define x '())
(define y '())
(eq? x y)      => #t

现在取决于实现 eq? 可能会或可能不会为原始值(例如数字、字符串等)返回 #t.例如:

Now depending upon the implementation eq? may or may not return #t for primitive values such as numbers, strings, etc. For example:

(eq? 2 2)     => depends upon the implementation
(eq? "a" "a") => depends upon the implementation

这就是 eqv? 谓词出现的地方.eqv?eq? 谓词完全相同,除了它总是为相同的原始值返回 #t.例如:

This is where the eqv? predicate comes into picture. The eqv? is exactly the same as the eq? predicate, except that it will always return #t for same primitive values. For example:

(eqv? 2 2)     => #t
(eqv? "a" "a") => depends upon the implementation

因此 eqv?eq? 的超集,在大多数情况下,您应该使用 eqv? 而不是 eq?.

Hence eqv? is a superset of eq? and for most cases you should use eqv? instead of eq?.

最后我们来到 equal? 谓词.equal? 谓词与 eqv? 谓词完全一样,除了它也可以用来测试两个列表、向量等是否有对应的元素满足eqv? 谓词.例如:

Finally we come to the equal? predicate. The equal? predicate is exactly the same as the eqv? predicate, except that it can also be used to test whether two lists, vectors, etc. have corresponding elements which satisfy the eqv? predicate. For example:

(define x '(2 3))
(define y '(2 3))
(equal? x y)      => #t
(eqv? x y)        => #f

一般来说:

  1. 当您希望测试两个数字是否相等时,请使用 = 谓词.
  2. 当您希望测试两个非数字值是否相等时,请使用 eqv? 谓词.
  3. 当您希望测试两个列表、向量等是否相等时,请使用 equal? 谓词.
  4. 不要使用 eq? 谓词,除非您确切地知道自己在做什么.
  1. Use the = predicate when you wish to test whether two numbers are equivalent.
  2. Use the eqv? predicate when you wish to test whether two non-numeric values are equivalent.
  3. Use the equal? predicate when you wish to test whether two lists, vectors, etc. are equivalent.
  4. Don't use the eq? predicate unless you know exactly what you're doing.

这篇关于Scheme中的eq?、eqv?、equal?和=有什么区别?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆