我想 setf 结构的不同字段取决于某个变量。我决定使用以下方法:

使用该字段的登录名来生成字符串:

(setq my-string (format nil "STRUCT-ESTADISTICAS-NUM-~S" x))

然后将实习生与Funcall一起使用:

(funcall (intern my-string) *estadisticas*)

此呼叫返回结构字段的正确值,但是如果我尝试 setf 要修改此值,它抱怨说:

(setf (funcall(intern my-string) *estadisticas*) 0)
Error: `(SETF FUNCALL)' is not fbound

我可以理解为什么它不起作用,但是我找不到修改结构字段的方法。任何的想法?谢谢你。

有帮助吗?

解决方案

您想通过其名称来调用结构的作者函数,而作者的名称是列表 (setf accessor-name);所以

(funcall (fdefinition (list 'setf (intern my-string))) 0 estadisticas)

编辑:

看不到其余的代码,很难理解出了什么问题。在SBCL上,这对我有用:

(defstruct point x y)
(let ((point (make-point :x 1 :y 2)))
  (funcall (fdefinition (list 'setf (intern "POINT-X"))) 10 point)
  point)

以上评估

#S(POINT :X 10 :Y 2),

正如预期的。

其他提示

动机:

结构是一个相对较低的设施。 “速度”是一个重要的设计目标。标准不支持通过作者函数的间接功能(正如我阅读的那样)。今天,将CLOS用作默认值,除非需要更好的结构效率(有时可以更快地阅读和用结构写入插槽)。

首先 - 样式:

不要使用实习生,请使用Find-Mbol。还指定软件包,否则Find-Mbol将使用 *软件包 *的运行时值作为软件包

第二-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)).

因此,构建这样的名称(setf foo-bar)并试图找到一个函数将失败,因为删除未定义此类函数。

在用户代码(setf(foo-bar some-scruct)42)中,作品是基于DefStruct提供的定义SETF扩展,但不基于定义的SETF访问器函数。

一些常见的LISP实现可能会提供作者功能作为ANSI CL的非标准扩展。

可能的解决方案:

a)使用关闭类,DefClass做您想要的

b)自己写作者的功能

(defun (setf foo-bar) (new-value struct)
   (setf (foo-bar struct) new-value))

现在:

(funcall (fdefinition '(setf foo-bar)) 300 *foo*)

上面有效。

c)(SETF插槽值) - 某些实现的另一个非标准功能。

在普通LISP的某些实现中,这不仅适用于关闭类,而且适用于结构:

(setf (slot-value some-struct 'bar) 42)

我不确定Allegro CL是否确实支持了这一点,但这很容易找到。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top