如何在CLISP中通过变量为propertyList命名及修复函数调用问题
问题1:如何在CLISP中通过变量为propertyList赋予名称?
在Common Lisp(包括CLISP)里,给自定义的property list(也就是你这里的嵌套列表结构)绑定变量名非常直接,本质就是把plist赋值给变量,这里有两种常用方式:
定义全局变量:如果希望这个plist能在全局作用域访问,用
defparameter或defvar(两者的区别是defvar只会在变量未定义时赋值,defparameter总是会覆盖原有值):;; 定义全局变量*my-plist*,存储你的property list (defparameter *my-plist* '((man noun singular) (woman noun singular) (likes verb singular) (a article) (man verb plural)))之后你就可以直接用
*my-plist*来引用这个plist,比如(print *my-plist*)就能输出整个列表。局部/动态赋值:如果只是在局部作用域使用,或者临时赋值,用
setq(注意要确保变量已经被定义过,否则可能触发未定义变量的警告):;; 临时赋值给局部变量 (setq my-temp-plist '( (cat noun singular) (run verb plural) ))
不管哪种方式,变量名就相当于这个plist的"名称",后续通过变量就能操作这个plist的内容。
问题2:修复无法正常工作的
ct函数 先拆解你的原代码为什么失效:
(defun ct (x) (setq x '( (man noun singular) (woman noun singular) (likes verb singular) (a article) (man verb plural) ) ) )
当你调用(ct '(myplist))时,有两个核心问题:
- 你传递的参数是
'(myplist)——这是一个包含符号myplist的列表,而不是符号myplist本身; - 函数里的
setq x只是修改了函数内部的局部变量x,完全不会影响外部的myplist变量——函数参数是局部绑定,修改它和外部变量没有任何关系。
修复方案
如果你想实现的是「把指定的plist赋值给名为myplist的全局变量」,可以修改函数为操作符号的值,代码如下:
(defun ct (var-symbol) ;; 用setf修改符号对应的全局变量值 (setf (symbol-value var-symbol) '((man noun singular) (woman noun singular) (likes verb singular) (a article) (man verb plural))))
然后正确调用:
(ct 'myplist) ;; 传递符号myplist,而不是列表'(myplist)
调用后,全局变量myplist就会被赋值为你指定的plist,之后直接输入myplist就能看到内容了。
额外说明
如果你确实需要处理像'(myplist)这样的列表参数(虽然不推荐,不符合Lisp习惯),可以修改函数取出列表中的符号:
(defun ct (var-list) (setf (symbol-value (car var-list)) ;; 取列表第一个元素作为目标符号 '((man noun singular) (woman noun singular) (likes verb singular) (a article) (man verb plural))))
调用(ct '(myplist))就会生效,但更建议直接传递符号。
内容的提问来源于stack exchange,提问作者SAQ
相关产品推荐
相关产品推荐

