通用Lisp中的包通信问题
我定义了两个包:通用Lisp中的包通信问题,lisp,common-lisp,Lisp,Common Lisp,我定义了两个包:game(文件game.lisp)和commands(文件commands.lisp),由game.asd文件加载。使用(symbol function(find symbol“test function”commands))调用命令函数(已导出)时遇到问题,它返回函数未定义,即使(find symbol“test function”commands)返回函数是外部的,并且属于命令包 game.asd文件上的代码是: (asdf:defsystem "game" :depen
game
(文件game.lisp
)和commands
(文件commands.lisp
),由game.asd
文件加载。使用(symbol function(find symbol“test function”commands))
调用命令函数(已导出)时遇到问题,它返回函数未定义,即使(find symbol“test function”commands)
返回函数是外部的,并且属于命令
包
game.asd
文件上的代码是:
(asdf:defsystem "game"
:depends-on (#:cl-ppcre)
:components ((:file "game")
(:file "commands")))
game.lisp
以以下内容开头:
(defpackage :game
(:use :cl :cl-ppcre))
(defpackage :commands
(:use :cl)
(:export "test-function"))
commands.lisp
以以下内容开头:
(defpackage :game
(:use :cl :cl-ppcre))
(defpackage :commands
(:use :cl)
(:export "test-function"))
我是否需要使用软件包中的功能?
在game.lisp
中,我调用存储在commands.lisp
文件中的命令,其中一些调用game.lisp
上的一些函数,例如:
(defun test-function ()
(progn
(format *query-io* "Worked!~%")
(start)))
test函数
位于commands包中,但调用start
函数,该函数属于game.lisp
当我调用(symbol函数(查找symbol“test function”命令))时,我希望调用测试函数
函数摘要
我的主要建议是,您应该有单独的包,其中包含用户命令和Lisp代码
您不必为每个Lisp文件创建单独的包
细节
你确实需要
宏(它不是函数!),以确保代码驻留在
正确的包装,因为
仅仅创造
包,它不会改变
因此,我建议如下:
文件夹
game.asd
package.lisp
game.lisp
commands.lisp
然后使用添加
命令到*命令包*
并查找它们
(defun test-command ()
(format t "test-command~%")
(start))
(intern 'test-command *commands-package*)
您还可以为此定义自己的宏:
(defmacro defcommand (name arglist &body body)
`(progn
(intern (symbol-name ',name) *commands-package*)
(defun ,name ,arglist ,@body)))
(defcommand test-command ()
(format t "test-command~%")
(start))
挑剔
- 不要将函数体包装在显式
,因为
这是为你做的
- 找到一个
,而不是
- 别忘了把论点讲清楚
我不知道你为什么要做
查找符号之类的事情。如果您只想调用另一个包中定义的函数,则有两个选项:
- 如评论中所述,您可以
使用另一个软件包:
- 或者使用
(命令:测试函数)
(如果函数未导出,则使用双冒号:
)调用函数
以下是新项目的示例定义:
另请参见处理软件包的提示:您可以:使用…:命令
package in:game
将导出的函数设置为“本地”:(defpackage:game(:use:cl:cl-ppcre:commands))
。我在game.asd上切换了初始化顺序(否则,系统返回找不到命令包)并将命令
包添加到游戏
包定义的使用
,但错误仍然出现(函数未定义)默认情况下,符号在Common Lisp中为大写。使用“TEST-FUNCTION”作为符号名字符串。关于宏,在尝试加载和编译命令时,会出现错误绑定SB-IMPL::name时,值TEST-COMMAND不是字符串类型。lisp
。为了确保这一点,我需要在REPL中加载并编译game.asd文件,调用(asdf:load system'game)
并将包更改为:game
?非常感谢您的帮助。无论您是在CL-USER软件包中还是在游戏软件包中与您的代码交互,这都只是个人方便的问题。Uiop(ASDF的一部分)具有Uiop:standard case symbol name
,它至少还支持Allegro的“现代”模式。感谢您的回答和提供的资料,但这样做是行不通的。在这个问题中,我解释了为什么我需要查找符号
(从用户输入调用函数,从字符串转换而来)。
(defun test-command ()
(format t "test-command~%")
(start))
(intern 'test-command *commands-package*)
(defmacro defcommand (name arglist &body body)
`(progn
(intern (symbol-name ',name) *commands-package*)
(defun ,name ,arglist ,@body)))
(defcommand test-command ()
(format t "test-command~%")
(start))
(defpackage :game
(:use :cl
:cl-ppcre
:commands))
(in-package :game)