首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >为什么CLOS插槽可以不受约束?

为什么CLOS插槽可以不受约束?
EN

Stack Overflow用户
提问于 2014-06-22 05:41:31
回答 2查看 960关注 0票数 0

据说,只有公共Lisp中的特殊变量才能被解除约束。对于所有词法变量,默认值为nil。我认为类插槽存在于类似闭包的地方,但显然它们不存在。

如果我定义一个没有:initform参数的CLOS插槽(希望它们无论如何都绑定到nil ),并且在创建实例时不提供值,我将得到一个带有未绑定插槽的实例。为甚麽会这样?不方便。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-06-22 08:47:42

CLOS实例不是闭包

CLOS实例通常不是作为闭包实现的。那就很难了。它们是一些数据结构,具有类似于插槽向量的东西。类似于通用Lisp的结构。CLOS实例和结构之间的差异使其复杂化: CLOS实例有可能在运行时更改槽数,并且可以在运行时更改CLOS实例的类。

确保插槽有一个NIL

使用一些先进的CLOS,您可以确保插槽有一个零值。注意,在我的示例中,包CLOS中的函数可能位于CL中的另一个包中。

此函数查找实例的所有插槽。如果一个插槽未绑定,它将被设置为NIL

代码语言:javascript
复制
(defun set-all-unbound-slots (instance &optional (value nil))
  (let ((class (class-of instance)))
    (clos:finalize-inheritance class)
    (loop for slot in (clos:class-slots class)
          for name = (clos:slot-definition-name slot)
          unless (slot-boundp instance name)
          do (setf (slot-value instance name) value))
    instance))

我们做了一个混合班:

代码语言:javascript
复制
(defclass set-unbound-slots-mixin () ())

修补程序将在初始化对象后运行。

代码语言:javascript
复制
(defmethod initialize-instance :after ((i set-unbound-slots-mixin) &rest initargs)
  (set-all-unbound-slots i nil))

示例

代码语言:javascript
复制
(defclass c1 (set-unbound-slots-mixin)
  ((a :initform 'something)
   b
   c))


CL-USER 1 > (describe (make-instance 'c1))

#<C1 4020092AEB> is a C1
A      SOMETHING
B      NIL
C      NIL
票数 5
EN

Stack Overflow用户

发布于 2014-06-24 12:45:36

对于像按需计算时隙值这样的事情来说,它非常方便,在这种情况下,值有时可能为零。当访问未绑定时隙时,CLOS通常调用SLOT-UNBOUND泛型函数,这表示错误。但是,您可以将SLOT-UNBOUND专门化为按需计算和存储值,而不是错误。后续访问将直接使用时隙值,您可以使用SLOT-MAKUNBOUND刷新槽“缓存”。

您可以使用某个类型的前哨“非绑定”值来完成这一任务,但是使用内置的功能非常方便。

slot-unbound使用示例:

代码语言:javascript
复制
(defclass foo ()
  ((bar :accessor bar)
   (baz :accessor baz)))

(defmethod slot-unbound (class (instance foo) slot-name)
  (declare (ignorable class))
  (setf (slot-value instance slot-name) nil))

在行动中:

代码语言:javascript
复制
CL-USER> (defparameter *foo* (make-instance 'foo))
*FOO*
CL-USER> (bar *foo*)
NIL
CL-USER> (setf (baz *foo*) (not (baz *foo*)))
T
票数 8
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/24348474

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档