普通Lisp。
我试图确定一个字符串是否存在于一个给定的列表中。
我的目标是要有 (member searched-string my-list)
但我一直得到 NIL
.
为什么 (member "foo" '("foo" "bar"))
返回 NIL
?
这是因为 (eql "foo" "foo") ; ==> nil
. 虽然在CLHS中没有记载 member
用途 #'eql
作为标准测试。要让它使用 #'equal
也评价 t
的结构,显示相同的
(equal "foo" "foo") ; ==> t
(member "foo" '("foo" "bar") :test #'equal) ; ==> ("foo" "bar")
字符串是以字符向量的形式存储的,因此,除非它是同一个对象。eq
和 eql
将评估到 nil
而 equal
检查字符串中的所有字符是否为 eql
.
注意: (eql "foo" "foo")
也可以是 t
. 由于它是文数,因此是常量数据,同样的代码编译后在某些实现中只存储了 "test"
一次,使它们的指针相等(eq
).
的默认值。:test
关键字参数是 #'eql
:
如果没有a
:test
也不是:test-not
参数,就像提供了一个:test
的论点#'eql
被提供。
字符串不是数字,也不是字符,所以两个字符串是 eql
才会 eq
(相同),但在你的例子中,你可能有两个不同的字符串分配。你可以在以下地方进行优化 string=
字符串被编译器内置于其中,使它们成为 eq
但这将是一个实施细节。
下面,同样的 foo
字符串用于建立列表,并作为参数给 member
而调用实际上是在找值。
(let ((foo "foo"))
(member foo (list foo "bar")))
=> ("foo" "bar")
但更多的是,你想传递一个字符串比较函数,比如: string-equal
(不区分大小写)或 string=
(精确的情况),或者干脆就是一个通用的平等谓词;下面两个例子都能找到sarch字符串。
(member "foo" '("foo" "bar") :test #'equal)
(member "FOO" '("foo" "bar") :test #'equalp)