为什么有这么多方法来比较平等?

时间:2014-06-04 08:01:13

标签: comparison lisp common-lisp equality

如果我想比较两个值是否相等,则有许多选项,例如:

  • eq代码
  • =代表数字
  • char-equal代表字符
  • string-equal字符串
  • eql代码,数字和字符串
  • equal除了符号之外的所有内容
  • ...

(我希望到目前为止我能做到这一点。)

现在,作为一个Lisp初学者,我的问题是:为什么?这仅仅是出于“历史原因”还是存在所有这些可能性的真正好处?

我知道为什么 -questions总是很难回答,可能是基于意见的,但我认为(猜测)有一些最佳实践,这些实践是高级Lisp开发人员共同商定的。< / p>

3 个答案:

答案 0 :(得分:3)

有很多因为有针对某些类型优化的专业比较函数。使用它们可能会提供更好的性能。

我在Land of Lisp

中读到的这条简单规则
  • 使用eq比较识别相同的对象(指针相等)
  • equal用于看起来相同的所有内容

现在有时候你想测试一个字符串是否等同于区分大小写,然后equal不会这样做,因为&#34; test&#34;和&#34; TEST&#34;看起来不一样。 string-equal将是正确的选择。

在比较不同类型的数字时,例如3.0和3,它们看起来不一样。但是,如果您(= 3 3.0) T equalp,那么如果将fixnum转换为浮点数,则它们代表相同的值。

同样equal=类似,不同之处在于字符串不区分大小写,数字类似equalp。我不完全确定,但在我看来,第三条规则是:

  • 使用{{1}}表示相同的内容

因此,您只需使用那些通用的3个,但有些情况下您可能需要搜索CLHS以获取专门的相等运算符。

答案 1 :(得分:2)

您实际上可以将所有内容与eqeqlequalequalp进行比较。但要自己选择,需要什么:

很容易认为eq比较指针。因此,符号(因为唯一符号只输入一次包,并且在每种情况下它的地址都相同)将返回true。

CL-USER> (eq 'a 'a)
T

接下来,不同的列表,即使包含相同的值,也不相等(以eq表示)。它们有不同的地址,它们是不同的对象。

CL-USER> (defparameter *a* '(1 2))
*A*
CL-USER> (defparameter *b* '(1 2))
*B*
CL-USER> (eq *a* *b*)
NIL

但它并不总是正确的,例如,如果你正在处理文字对象:

CL-USER> (lambda nil '(1 2 3))
#<FUNCTION :LAMBDA NIL '(1 2 3)>
CL-USER> (eq * *)
T

虽然:

CL-USER> (eq '(1 2 3) '(1 2 3))
NIL

棘手?您可能期望包含相同数字的不同变量的值不相等,因为数字应该占用不同的内存块,但是......

CL-USER> (defparameter *c* 5)
*C*
CL-USER> (defparameter *d* 5)
*D*
CL-USER> (eq *c* *d*)
T

eq函数的描述说明了相同的对象,因此数字5在任何地方都是相同的对象。

接下来,eql函数在eq上定义,在以下情况下评估t

  • 如果x和y为eq
  • 如果x和y都是相同类型和相同值的数字。
  • 如果它们都是代表相同角色的字符。

并且equalequalp处理视觉上相似的&#39;对象。

为什么这么多人呢?想想你自己:在像LISP这样的语言中你不明确地使用指针你可能想在列表中找到完全相同的对象(在同一地址)或任何地方。所以你需要在这个&#39;指针上运行的函数#39;水平。接下来很明显,你需要正常的&#39;比较功能和它们在这里。差异是微妙的,有点历史性,但通常有用它们。

同样重要的是要注意,这4个基本比较函数中的一些具有应用于某些类型的数据的附加含义。例如,equal用于以区分大小写的方式比较字符串,而equalp用不区分大小写的方式进行比较。

CL-USER> (equal "My String" "My String")
T
CL-USER> (equal "My String" "My string")
NIL
CL-USER> (equalp "My String" "My string")
T

要继续使用字符串示例,这里有许多函数,例如string=等。为什么?那是什么&#39; The Common Lisp Cookbook&#39;表示:

  

如果您正在部署实现定义的字符属性,则您将要使用这些属性。在这种情况下,请查看供应商的文档。

然而,在绝大多数情况下,4个基本功能就足够了。

答案 2 :(得分:2)

基本上有两组比较:

  • 通用:EQ(指针),EQL(指针+数字+字符),EQUAL,EQUALP
  • type specific:string-equal,string =,...

通用比较试图为典型(主要)符号编程中的基本用例提供功能。

特定于类型的比较被认为表达(并且可能检查)参数是某种类型的。它们还提供有效的实现。添加它们是为了使这些函数可以在代码中使用,这需要扩展到或调用特定和有效的函数。