3

如果您将 onlisp 中提供的 aif 代码放在一个包中并尝试在另一个包中使用它,则会遇到 packagename:it 不是外部的问题。

(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只能通过it而不是访问packagename:it

4

1 回答 1

5
(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))))
于 2012-09-12T16:07:21.777 回答