Common lisp 如何将aif更改为能够访问';它';在宏调用中,不进行';它';包装中的公共物品
如果您将中提供的aif代码放在一个包中,并尝试在另一个包中使用它,那么您运行的问题是packagename:它不是外部的Common lisp 如何将aif更改为能够访问';它';在宏调用中,不进行';它';包装中的公共物品,common-lisp,Common Lisp,如果您将中提供的aif代码放在一个包中,并尝试在另一个包中使用它,那么您运行的问题是packagename:它不是外部的 (in-package :packagename) (defmacro aif (test-form then-form &optional else-form) ‘(let ((it ,test-form)) (if it ,then-form ,else-form))) 通缉令语法 (in-package :otherpackage) (aif
(in-package :packagename)
(defmacro aif (test-form then-form &optional else-form)
‘(let ((it ,test-form))
(if it ,then-form ,else-form)))
通缉令语法
(in-package :otherpackage)
(aif (do-stuff)
(FORMAT t "~a~%" it)
(FORMAT t "just got nil~%"))
如何在代码中修复此行为,而不使变量在包声明中为外部变量,并且仅通过it
而不是packagename:it
访问it
(defmacro aif (test then &optional else)
;;; read-from-string will intern the symbol
;;; in the current package, with the correct
;;; read-table-case
(let ((it (read-from-string "it")))
`(let ((,it ,test))
(if ,it ,then ,else))))
或者这也有效:
(defmacro aif (test then &optional else)
;;; (intern "IT") or (intern "it") will work
;;; as well, depending on your readtable settings.
;;; using string or symbol-name gets around that.
(let ((it (intern (string 'it))))
`(let ((,it ,test))
(if ,it ,then ,else))))
它可以工作,但不是有一种更优雅的方式,让后来的宏读者知道这些“奇怪”行的意图是什么?哪些行是“wierd”行?在我看来,
(让((从字符串“it”)读取)
行不自我解释intern
也在当前包中实习符号(默认),并明确表示这是你的意图。这就是它的目的。