如何在Common Lisp的defmethod中对字符串进行精确匹配特化?
针对字符串的defmethod精确匹配特化方案
你报错的原因是eq/equal/string=是普通比较函数,不符合Common Lisp参数特化器的语法规范。合法的精确值特化只能用(eql 具体值)的形式,数字是如此,字符串也一样。
基于对象身份的精确匹配
如果只需要匹配同一个内存对象的字符串(比如代码里的字面量字符串,多数实现会自动重用这类对象),可以直接用(eql 字符串)做特化:
(defgeneric person (attribute) (:documentation "attributes of a person")) ;; 通用字符串处理方法 (defmethod person ((a string)) (format t "Received string: ~a" a)) ;; 针对"Alice"的精确特化方法 (defmethod person ((a (eql "Alice"))) (format t "ALICE DETECTED!!!"))
测试效果:
> (person "Bob") ;; 输出:Received string: Bob > (person "Alice") ;; 输出:ALICE DETECTED!!!
注意:这种方式只对同一个对象的字符串生效。如果传入的是动态创建的字符串(比如(copy-seq "Alice")),因为是新的内存对象,不会触发特化方法:
> (person (copy-seq "Alice")) ;; 输出:Received string: Alice
基于内容的精确匹配(不受对象身份限制)
如果需要只要字符串内容相同就触发特化逻辑,标准Common Lisp没有直接的特化器支持,可通过:around方法实现:
(defgeneric person (attribute) (:documentation "attributes of a person")) ;; 通用字符串处理方法 (defmethod person ((a string)) (format t "Received string: ~a" a)) ;; 用:around方法做内容匹配分发 (defmethod person :around ((a string)) (cond ((string= a "Alice") (format t "ALICE FOUND!!!")) ((string= a "Bob") (format t "BOB SPECIAL CASE!!!")) (t (call-next-method)))) ; 其他字符串走通用逻辑
测试效果:
> (person "Alice") ;; 输出:ALICE FOUND!!! > (person (copy-seq "Bob")) ;; 输出:BOB SPECIAL CASE!!! > (person "Charlie") ;; 输出:Received string: Charlie
内容的提问来源于stack exchange,提问作者Vinn
相关产品推荐
相关产品推荐

