如果我想比较两个值是否相等,则有很多选择,例如:
eq
用于符号=
对于数字char-equal
对于字符string-equal
对于字符串eql
用于符号,数字和字符串equal
除了符号以外的所有东西(我希望到目前为止我做对了。)
现在,作为Lisp初学者,我的问题是:为什么?这仅仅是出于“历史原因”还是拥有所有这些可能性的真正好处?
我知道为什么-问题总是很难回答,并且可能是基于观点的,但是我认为(猜测)有些最佳实践是Lisp高级开发人员普遍同意的。
实际上,你可以比较的一切eq
,eql
,equal
和equalp
。但是自己选择,需要什么:
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
在以下情况下求值:
eq
。而且equal
,equalp
处理“视觉上类似的”对象。
为什么这么多?自己想想:在LISP之类的语言中,您不能显式地使用指针,因此您可能希望在列表或任何地方找到完全相同的对象(在相同的地址)。因此,您需要在此“指针”级别起作用的函数。接下来很明显,您需要“正常”的比较功能,这就是它们的所在。差异是微妙的并且有些历史性,但是将它们全部都有用。
同样重要的是要注意,这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=
,为什么?那就是《 The Lisp Common Cook》的意思:
如果要部署实现定义的字符属性,则需要使用它们。在这种情况下,请检查供应商的文档。
但是,在大多数情况下,这四个基本功能就足够了。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句