EQV?功能(DrRacket)

时间:2013-11-01 01:36:34

标签: lisp scheme racket

DrRacket中的等式函数有很多复杂性。他们之间有微妙的差异,我无法理解。

你能解释为什么这两个结果不同吗?为什么例如'a'=='a',但是“abc”!=“abc”?

(eqv? (integer->char 955) (integer->char 955))
; => true

(eqv? (number->string 955) (number->string 955))
; => false

3 个答案:

答案 0 :(得分:1)

eqv?基本上进行身份比较,但在数字和字符的情况下,则比较值。这就是值为955的两个字符比较相同的原因。

身份是什么意思?考虑一下:

(define a (number->string 955))
(define b (number->string 955))
(string-set! a 0 #\0)
(printf "a = ~s, b = ~s, (eqv? a b) = ~a~%" a b (eqv? a b))

您会注意到只有a的字符串被更改,而不是b的字符串。那是因为它们是不同的字符串对象。

相反的情况是涉及别名时:

(define a (number->string 955))
(define b a)
(string-set! a 0 #\0)
(printf "a = ~s, b = ~s, (eqv? a b) = ~a~%" a b (eqv? a b))

此处,ab指向同一个字符串对象,string-set!的效果在两个地方均可见。

答案 1 :(得分:1)

虽然两个“(number-> string 955)”看起来相同,但它们在内存中返回两个单独的对象。考虑到这一点,让我们进行比较:

(eq? (number->string 955) (number->string 955))
#f

这是假的,因为eq?关心同一性,即:被比较的内容与内存中的对象完全相同。这个检查很快,但通常不是你想要的。

(eqv? (number->string 955) (number->string 955))
#f

这又是假的,原因与eq相同? - 这些与内存中的对象不同。 EQV?但是对数字和字符例外:它会按值比较那些,所以两个数字是eqv?如果他们有相同的价值。这仍然很快,通常是你在进行数字相等测试时所需要的。

(equal? (number->string 955) (number->string 955))
#t

现在这是真的。为什么?对象仍然不同,但相同?为字符串(以及其他数据类型)提供例外,但我会保持简单。当平等?给出了字符串,它在词法上比较字符串:所以如果它们是相同的长度和相同的字符序列,它们是“相等的”。这是你想要的字符串检查。

答案 2 :(得分:1)

RNRS规范中有两页与eq?,eqv?相关,等于?和=。这是Draft R7RS Specification。看看(第30和39页)!

对于eqv ?,如果符合以下条件,则返回#t:

  • obj1和obj2都是字符并且是相同的字符 根据char =?程序(第6.6节)。
  • obj1和obj2是对,向量,字节向量,记录或字符串 它表示商店中的相同位置(第3.4节)。

在您的情况下,number->string会返回商店中的新“位置”,从而返回#f。 (Scheme标准不要求number->string返回新位置;返回相同的字符串将是优化。)integer->char返回相同的char