common-lisp - 常见的 lisp : slot-value for defstruct structures

标签 common-lisp structure accessor clos ccl

在常见的 lisp 中,我可以使用什么来使用插槽名称/符号访问结构插槽?

我想要的是

(defstruct point (x 0) (y 0))    
(defmacro -> (struct slot) `(slot-value ,struct ,slot))

(setf p (make-point))
(setf (slot-value p 'x) 1)
(setf (-> p 'y) 2)

我正在使用 clozure cl,并且在 clozure cl 中这有效。但是,AFAIK 这是非标准行为(相当于“未定义行为”C++)。我不打算切换到另一个 CL 实现,所以我应该继续使用 slot-value对于结构,或者有更好的方法吗?

最佳答案

通常你会使用带有结构的访问器函数。

您的代码定义了访问函数 point-xpoint-y .你可以使用那些。

您也可以使用SLOT-VALUE具有支持它的实现结构。我想这是大多数实现(GCL 将是一个异常(exception))。有 Lisp 软件假定 SLOT-VALUE适用于结构。我认为实现不会取消对它的支持。它不在标准中,因为一些实现者不想在已部署的应用程序中提供此功能。

所以两种方式都可以。

如果您想使用短名称,请使用访问器:

CL-USER 109 > (defstruct (point :conc-name)
                (x 0) (y 0))
POINT

CL-USER 110 > (make-point :x 5 :y 3)
#S(POINT :X 5 :Y 3)

CL-USER 111 > (setf p1 *)
#S(POINT :X 5 :Y 3)

CL-USER 112 > (x p1)
5

CL-USER 113 > (setf p2 (make-point :x 2 :y 3))
#S(POINT :X 2 :Y 3)

CL-USER 114 > (list p1 p2)
(#S(POINT :X 5 :Y 3) #S(POINT :X 2 :Y 3))

CL-USER 115 > (mapcar 'x (list p1 p2))
(5 2)

然后必须通过包来防止各种访问器函数之间的名称冲突。

如果你想写 SLOT-VALUE 的更短版本,那也不错。写一个宏。或者写一个内联函数。当然——为什么不呢?

正如我所说,SLOT-VALUE在大多数实现中与结构一起使用。在这种情况下,您不应该关心 ANSI CL 规范没有定义它。在许多方面,实现扩展了 ANSI CL 规范。例如 SLOT-VALUE处理结构,将流实现为 CLOS 类,将条件实现为 CLOS 类,提供元对象协议(protocol),...

关于common-lisp - 常见的 lisp : slot-value for defstruct structures,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17247540/

相关文章:

list - Lisp - 所有列表的第一个元素(表面层)

ios - Swift 删除结构数组

c - 原始代码和修改后的代码有什么区别?

java - 使用反射设置对象属性

java - 修改器和访问器(使用继承)

lisp - Lisp 文件扩展名的约定是什么?

ubuntu - 无法使用 UFFI 加载 libncurses

javascript - JavaScript 中的有效属性名称、属性分配和访问

recursion - LISP 迭代到递归

vb.net - 在哪里保留结构 : class, 模块或没有?