我想在另一个名称很长的包中使用一些函数(例如,“sb-bsd-sockets”),我必须这样写:
(defun myfun (...)
(sb-bsd-sockets:socket-bind ...)
(sb-bsd-sockets:socket-listen ...)
...)
有没有办法导入一些仅在 myfun
中可用的符号(没有任何性能损失)?
最佳答案
以下是我首先想到的(简单的树遍历和符号名称替换)。
应该注意的是,问题是关于导入 符号的,而下面的代码并没有这样做。它只是为您添加了难看的 package-name::部分。
(defmacro with-symbols-from ((package-name &rest symbols) &body body)
(let ((f-symbols (loop :for s :in symbols :collect
(intern (symbol-name s) package-name))))
`(progn
,@(loop :for symbol :in symbols :for f-symbol :in f-symbols
:with body = body
:do (setf body (subst f-symbol symbol body :test #'eq))
:finally (return body)))))
使用示例:
CL-USER> (with-symbols-from (:cffi foreign-alloc mem-aref)
(let ((a (foreign-alloc :int)))
(setf (mem-aref a :int) 1)
(mem-aref a :int)))
1
以上扩展为:
(PROGN
(LET ((A (CFFI:FOREIGN-ALLOC :INT)))
(SETF (CFFI:MEM-AREF A :INT) 1)
(CFFI:MEM-AREF A :INT)))
关于import - 普通口齿不清 : How to import symbols of other packages inside a lexical scope only?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18679993/