Common LISP中position函数与gensym配合出现异常的问题咨询
问题原因
你遇到的问题核心是**#:开头的符号是“未进包的匿名符号”**——每次你写出#:G808,LISP都会生成一个全新的符号对象,哪怕名字字符串看起来一模一样,它们的身份(内存地址)是完全不同的。
你执行的(position '#:G808 (list '#:G808))里,第一个#:G808和列表里的#:G808其实是两个毫不相干的符号,position默认用eql比较(符号的eql判断是看是不是同一个对象),自然找不到匹配,返回nil。
而gensym生成的就是这种未进包的匿名符号,所以直接写字面量#:xxx永远无法匹配之前gensym生成的符号——因为每次都是新的。
解决方法
- 正确做法:把
gensym生成的符号存到变量里,用变量引用去比较,确保是同一个对象:(let ((g (gensym))) (position g (list g))) ; 此时返回0,符合预期 - 特殊场景(按符号名匹配):如果一定要通过符号的名字字符串来匹配(不推荐,存在同名符号混淆风险),可以指定
position的比较函数为string=:(position '#:G808 (list '#:G808) :test #'string=) ; 返回0,通过名字匹配
内容的提问来源于stack exchange,提问作者Spectorsky
相关产品推荐
相关产品推荐

