Common Lisp中类似OOP访问器/getter的自动翻转布尔值实现方法
实现方案
核心使用Common Lisp自带的define-symbol-macro(符号宏)能力,结合统一的生成宏即可解决你提到的两个痛点:
;; 统一的翻转布尔值定义宏 (defmacro def-toggling-bool (name &optional initial-value) (let ((private-var (gensym (string name)))) `(progn ;; 生成私有存储变量,外部无需直接访问 (defparameter ,private-var ,(if initial-value initial-value nil)) ;; 定义符号宏,直接写变量名即可触发翻转逻辑 (define-symbol-macro ,name (progn (setf ,private-var (not ,private-var)) ,private-var)) ;; 可选:禁止直接赋值修改,避免破坏翻转逻辑 (defsetf ,name () (new-val) (declare (ignore new-val)) (error "不允许直接修改翻转布尔值 ~s" ',name))))) ;; 测试:创建名为a的翻转布尔,初始值默认nil (def-toggling-bool a) ;; 直接使用变量名,无需括号包裹 (format t "A -> ~d~%" a) (format t "A -> ~d~%" a) (format t "A -> ~d~%" a) (format t "A -> ~d~%" a)
运行输出和你的示例完全一致:
A -> T A -> NIL A -> T A -> NIL
优势说明
- 解决了需要
(A)格式调用的问题:符号宏在编译期会自动把变量名展开为翻转逻辑,访问方式和普通变量完全一致,哪怕是打印、逻辑判断场景都可以直接使用 - 解决了需要单独定义宏的问题:只需要调用一次
def-toggling-bool就可以生成任意多的翻转布尔值,支持自定义初始值
内容的提问来源于stack exchange,提问作者scorch855
相关产品推荐
相关产品推荐

