ait*_*zos 5 lisp common-lisp allegro-cl
我想setf根据某个变量来选择结构的不同字段。我决定使用以下方法:
生成一个带有字段访问者名称的字符串:
(setq my-string (format nil "STRUCT-ESTADISTICAS-NUM-~S" x))
Run Code Online (Sandbox Code Playgroud)
然后将intern与funcall一起使用:
(funcall (intern my-string) *estadisticas*)
Run Code Online (Sandbox Code Playgroud)
该调用返回结构字段的正确值,但是如果我尝试setf修改此值,它会抱怨说:
(setf (funcall(intern my-string) *estadisticas*) 0)
Error: `(SETF FUNCALL)' is not fbound
Run Code Online (Sandbox Code Playgroud)
我可以理解为什么它不起作用,但是我找不到修改结构域的方法。任何的想法?谢谢。
您想通过其名称调用该结构的writer函数,而writer的名称为list (setf accessor-name);所以
(funcall (fdefinition (list 'setf (intern my-string))) 0 estadisticas)
Run Code Online (Sandbox Code Playgroud)
没有看到其余的代码,很难弄清出了什么问题。在SBCL上,这对我有用:
(defstruct point x y)
(let ((point (make-point :x 1 :y 2)))
(funcall (fdefinition (list 'setf (intern "POINT-X"))) 10 point)
point)
Run Code Online (Sandbox Code Playgroud)
以上评估为
#S(POINT :X 10 :Y 2),
Run Code Online (Sandbox Code Playgroud)
如预期的那样。
动机:
结构是一个相对较低级别的工具。“速度”是重要的设计目标。该标准不支持通过writer函数进行间接寻址(在我阅读本文时)。如今,除非需要更高的结构效率(有时可以更快地读取和写入具有结构的插槽),否则将CLOS用作默认值。
第一-风格:
不要使用INTERN,请使用FIND-SYMBOL。还指定软件包,否则FIND-SYMBOL将使用* package *的运行时值作为软件包
第二-DEFSTRUCT
如果我正确地阅读了ANSI CL标准,那不是DEFSTRUCT像DEFCLASS那样为插槽创建写程序功能。
CL-USER 24 > (defstruct foo bar baz)
FOO
CL-USER 25 > #'(setf foo-bar)
Error: Undefined function (SETF FOO-BAR) in form (FUNCTION (SETF FOO-BAR)).
Run Code Online (Sandbox Code Playgroud)
因此,构造这样的名称(SETF FOO-BAR)并尝试为此找到一个函数将失败,因为DEFSTRUCT没有定义这样的函数。
用户代码(setf(foo-bar some-struct)42)的工作原理是基于DEFSTRUCT提供的定义的SETF扩展,而不是基于定义的SETF访问器函数。
一些Common Lisp实现可能提供编写器功能,作为ANSI CL的非标准扩展。
可能的解决方案:
a)使用CLOS类,DEFCLASS可以满足您的要求
b)自己编写作家函数
(defun (setf foo-bar) (new-value struct)
(setf (foo-bar struct) new-value))
Run Code Online (Sandbox Code Playgroud)
现在:
(funcall (fdefinition '(setf foo-bar)) 300 *foo*)
Run Code Online (Sandbox Code Playgroud)
以上然后工作。
c)(SETF SLOT-VALUE)-一些实现的另一个非标准功能。
在Common Lisp的某些实现中,这不仅适用于CLOS类,而且适用于结构:
(setf (slot-value some-struct 'bar) 42)
Run Code Online (Sandbox Code Playgroud)
我不确定Allegro CL是否支持这一点,但这很容易发现。
| 归档时间: |
|
| 查看次数: |
1329 次 |
| 最近记录: |