为什么有这么多的方法来比较平等? [英] Why are there so many ways to compare for equality?

查看:140
本文介绍了为什么有这么多的方法来比较平等?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果我想比较两个相等的值,有很多选项,例如:





  • <$

    c $ c> char-equal
    字符

  • string-equal b $ b
  • eql 符号,数字和字符串

  • 等于


(我希望我有这个权利。)



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



我知道为什么很难回答,可能是基于意见的,但我认为(猜测)有最好的实践,通常由先进的Lisp开发人员同意。

解决方案

你实际上可以比较 eq eql / code>和 equalp 。但为自己选择所需的:



很容易认为 eq 比较指针。因此,符号(因为一个唯一的符号只进入一次包,它的地址在每种情况下都是相同的)使用它时会返回true。

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

接下来,不同的列表,相同的值,不相等(按 eq )。它们有不同的地址,它们是不同的对象。

  CL- (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

While:

  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



接下来, eql

code>函数定义在 eq ,它在以下情况下求值 t




  • 如果x和y为 eq


$ b

$ b

并且等于等于处理'视觉上相似的'对象。 >

为什么这么多?自己思考:在像LISP这样的语言中,你不能明确地使用指针,你可能希望在列表或任何地方找到完全相同的对象(在同一地址)。所以你需要在这个指针级别上执行的函数。接下来很明显,你需要正常比较函数,而在这里。差异是微妙的,有些历史,但它通常是有用的,它们都有。



还需要注意的是,这些4基本比较函数中的一些有额外的意义应用于某些类型的数据。例如等于用于以区分大小写方式比较字符串,而 equalp 在不区分大小写的情况下。 p>

  CL-USER> (等于My StringMy String)
T
CL-USER> (等于My StringMy string)
NIL
CL-USER> (equalpMy StringMy string)
T

例如,这里有许多函数,如 string = 等等。为什么?这就是Common Lisp Cookbook说的:


如果您要部署 字符属性。


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


If I want to compare two values for equality there are a number of options, such as:

  • eq for symbols
  • = for numbers
  • char-equal for characters
  • string-equal for strings
  • eql for symbols, numbers and strings
  • equal for everything but symbols

(And I hope I got this right so far.)

Now, as a Lisp beginner, my question is: Why is that? Is this just for "historical reasons" or is there a real benefit of having all these possibilities?

I know that why-questions are always hard to answer and may be opinion-based, but I think (guess) that there are best practices that are commonly agreed on by advanced Lisp developers.

解决方案

You actually can compare everything with eq, eql, equal and equalp. But choose for yourself, what's needed:

It's easy to think that eq compare pointers. Thus symbols (because a unique symbol enters package only once and its address is the same in every case you use it) will return true.

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

Next, different lists, even if contain the same values, are not equal (in terms of eq). They have different addresses, they are different objects.

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

But it's not always true, for example if you're dealing with literal object:

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

While:

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

Tricky? You may expect that values of different variables that contain the same numbers will not be equal, since the numbers should occupy different blocks of memory, but...

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

Description of eq function says about identical objects, so number five is the same object everywhere.

Next, eql function is defined upon eq, it evaluates t in the following cases:

  • If x and y are eq.
  • If x and y are both numbers of the same type and the same value.
  • If they are both characters that represent the same character.

And equal, equalp deal with 'visually similar' objects.

Why so many of them? Think for yourself: in language like LISP where you do not work with pointers explicitly you may want to find exactly the same object (at the same address) in list or anywhere.. So you need function that acts on this 'pointer' level. Next it's obvious that you need 'normal' comparison functions and here they are. Differences are subtle and somewhat historic, but it's often useful to have them all.

It's also important to note that some of these 4 base comparison functions have additional meaning being applied to certain types of data. For example equal works for comparison of strings in case-sensitive manner, while equalp in case-insensitive one.

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

To continue with the string example, here are many functions like string=, etc. Why? That's what 'The Common Lisp Cookbook' says:

You'll want to use these if you're deploying implementation-defined attributes of characters. Check your vendor's documentation in this case.

However, in vast majority of cases the 4 basic functions will be enough.

这篇关于为什么有这么多的方法来比较平等?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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