什么之间的区别eq
,eql
,equal
和equalp
,在Common Lisp的?我了解其中有些检查类型,有些检查所有类型,但究竟是哪一种呢?什么时候比另一个更好用?
什么之间的区别eq
,eql
,equal
和equalp
,在Common Lisp的?我了解其中有些检查类型,有些检查所有类型,但究竟是哪一种呢?什么时候比另一个更好用?
Answers:
(eq x y)
当且仅当x
和y
是相同的相同对象时为true 。如果
eql
谓词的参数为eq
,或者它们是具有相同值的相同类型的数字,或者它们是表示相同字符的字符对象,则该谓词为true 。如果
equal
谓词的参数是结构相似(同构)的对象,则该谓词为true。粗略的经验法则是,当且仅当两个对象的打印表示形式相同时,它们才相等。两个对象
equalp
相等。如果它们是字符并且满足字符相等,则忽略字母大小写和字符的某些其他属性;如果它们是数字并且具有相同的数值,即使它们是不同的类型;或者,如果它们具有全部组件equalp
。
以下是我链接到同一页面的一些示例:
(eq 'a 'b) is false.
(eq 'a 'a) is true.
(eq 3 3) might be true or false, depending on the implementation.
(eq 3 3.0) is false.
(eq 3.0 3.0) might be true or false, depending on the implementation.
(eq #c(3 -4) #c(3 -4))
might be true or false, depending on the implementation.
(eq #c(3 -4.0) #c(3 -4)) is false.
(eq (cons 'a 'b) (cons 'a 'c)) is false.
(eq (cons 'a 'b) (cons 'a 'b)) is false.
(eq '(a . b) '(a . b)) might be true or false.
(progn (setq x (cons 'a 'b)) (eq x x)) is true.
(progn (setq x '(a . b)) (eq x x)) is true.
(eq #\A #\A) might be true or false, depending on the implementation.
(eq "Foo" "Foo") might be true or false.
(eq "Foo" (copy-seq "Foo")) is false.
(eq "FOO" "foo") is false.
(eql 'a 'b) is false.
(eql 'a 'a) is true.
(eql 3 3) is true.
(eql 3 3.0) is false.
(eql 3.0 3.0) is true.
(eql #c(3 -4) #c(3 -4)) is true.
(eql #c(3 -4.0) #c(3 -4)) is false.
(eql (cons 'a 'b) (cons 'a 'c)) is false.
(eql (cons 'a 'b) (cons 'a 'b)) is false.
(eql '(a . b) '(a . b)) might be true or false.
(progn (setq x (cons 'a 'b)) (eql x x)) is true.
(progn (setq x '(a . b)) (eql x x)) is true.
(eql #\A #\A) is true.
(eql "Foo" "Foo") might be true or false.
(eql "Foo" (copy-seq "Foo")) is false.
(eql "FOO" "foo") is false.
(equal 'a 'b) is false.
(equal 'a 'a) is true.
(equal 3 3) is true.
(equal 3 3.0) is false.
(equal 3.0 3.0) is true.
(equal #c(3 -4) #c(3 -4)) is true.
(equal #c(3 -4.0) #c(3 -4)) is false.
(equal (cons 'a 'b) (cons 'a 'c)) is false.
(equal (cons 'a 'b) (cons 'a 'b)) is true.
(equal '(a . b) '(a . b)) is true.
(progn (setq x (cons 'a 'b)) (equal x x)) is true.
(progn (setq x '(a . b)) (equal x x)) is true.
(equal #\A #\A) is true.
(equal "Foo" "Foo") is true.
(equal "Foo" (copy-seq "Foo")) is true.
(equal "FOO" "foo") is false.
(equalp 'a 'b) is false.
(equalp 'a 'a) is true.
(equalp 3 3) is true.
(equalp 3 3.0) is true.
(equalp 3.0 3.0) is true.
(equalp #c(3 -4) #c(3 -4)) is true.
(equalp #c(3 -4.0) #c(3 -4)) is true.
(equalp (cons 'a 'b) (cons 'a 'c)) is false.
(equalp (cons 'a 'b) (cons 'a 'b)) is true.
(equalp '(a . b) '(a . b)) is true.
(progn (setq x (cons 'a 'b)) (equalp x x)) is true.
(progn (setq x '(a . b)) (equalp x x)) is true.
(equalp #\A #\A) is true.
(equalp "Foo" "Foo") is true.
(equalp "Foo" (copy-seq "Foo")) is true.
(equalp "FOO" "foo") is true.
更多注意事项:
未指定测试时,大多数CL函数隐式使用EQL
另请参阅STRING-EQUAL,=和TREE-EQUAL
EQ的核心通常是指针比较
和一个粗略的指导:
比较...使用... 对象/结构均衡器 NIL EQ(但函数NULL更简洁,可能更便宜) T EQ(或者只是值,但是您不在乎类型) 精确数字EQL 浮点数= 字符EQL或CHAR-EQUAL 列表,约束,序列均衡器(如果需要完全相同的对象) 相等(如果您只关心元素) 字符串EQUAL(区分大小写),EQUALP(不区分大小写) STRING-EQUAL(如果将符号投入混合) 树(列表列表)TREE-EQUAL(带有适当的:TEST参数)
注意,通常为了效率,EQ >> EQL >> EQUAL >> EQUALP。
从这里和我的老师的幻灯片
eq测试以查看其参数(由相同的计算机内存块表示)是否为相同的符号。
例如:
(eq'A'B)NIL
(eq'RAM'RAM)T
(eq(cons'a'b)(cons a'b')); 这是因为对两个缺点都进行了不同的调用,因此显然会为它们分配不同的内存块
eql首先进行测试以查看其参数是否满足EQ,如果不满足,则尝试查看它们是否为相同类型和值的数字。
例如:
(eql 4 4.0)无
(eql 4 4)T
现在注意一个区别:
(eq 4.0 4.0)NIL;取决于第一个(可接受的)answer
(eql 4.0 4.0)T中所述的平台T;参数的类型和值相同
在一些实现(EQ 4.0 4.0),因为它不是标准中所规定的实施是否应该保持只有一个数字和字符的副本存储在存储器,喜欢它的符号确实可以返回true)。作为一个经验法则 不使用等同于数字和字符,除非您真的知道自己在做什么。
equal是“ saner”比较函数。根据经验,您可以认为它告诉您两个对象看起来是否相同(结构相似或同构)。它可能是您要用于一般相等的运算符。对于数字,字符和符号,它的行为类似于eql,但是对于列表(约束)和字符串,它告诉它们是否包含元素
例如:
(等于4 4)T
(等于(+ 2 2)4)T
现在注意区别
(eql(cons'a'b)(cons'a'b))NIL
(等于(cons'a'b)(cons'a'b))T; 对于打印相同内容的事物,通常通常为true
equip就像平等,只是更先进。数字比较对类型不敏感。字符和字符串的比较不区分大小写。
例如:
(equalp(cons'a'b)(cons'a'b))T; 相等
现在注意区别
equal(4 4.0)NIL
equalp(4 4.0)T; 作为equalp不敏感地对待数字类型