是否存在Clojure的CLOS(Common Lisp Object System)之类的东西?
在Common Lisp中,如何覆盖CLOS类的默认字符串表示形式,以便调用format
或princ
打印可理解的内容,即使该类的对象嵌入其他类型(如列表或数组)中也是如此?
例如,如果我(format t "~a~%" x)
在x持有我的解决方案类的实例时调用,我希望它打印出类似的东西#<SOLUTION genes: #(1 2 3) scores: #(4 5) rank: 6>
而不是#<SOLUTION {BB7CD31}>
.
到目前为止,我已经设法弄清楚是编写自定义函数来处理我知道将包含此类实例的打印结构,但这很乏味.当然Lisp提供了一些免费获得此功能的方法吗?
我发现Common Lisp Object System(CLOS)优于传统的(基于类的)面向对象系统.CLOS的维基百科条目提到了两种方法之间的差异 - 主要是CLOS中的多个调度和类和方法的分离.这些仅仅是CLOS的差异或真正优势吗?
如何查看一个CLOS类是否是另一个CLOS类的子类?
如果你想使CLOS对象成为常见的lisp可打印(可读打印),那么如何在不使用打印和读取的情况下进行此操作.
我正在学习Common Lisp(使用Lispworks),而我正试图进入类系统.有一个名为standard-object的类,它被定义为
类标准对象是标准类的实例,是每个类的超类,它是标准类的实例,除了它自己.
(取自http://www.lispworks.com/documentation/HyperSpec/Body/t_std_ob.htm#standard-object)所以它是标准类的一个实例
另一方面,standard-class是standard-object的子类
>(subtypep 'standard-class 'standard-object)
=>T, T
Run Code Online (Sandbox Code Playgroud)
标准对象如何成为标准类的超类并同时成为它的实例?如果我们将标准类定义为子类型,我们应该在对其超类型(例如标准对象)进行定义后对其进行定义,那么如何将超类变为实例呢?或者我的逻辑是错的?
我有一个像这样的课
(defclass shape ()
((color :initform :black)
(thickness :initform 1)
(filledp :initform nil)
(window :initform nil)))
Run Code Online (Sandbox Code Playgroud)
如果我只知道这个类的实例,那么common-lisp中是否有一个函数如何获取这些插槽的列表?
我想使用Common Lisp CLOS对象作为哈希表中的键.我觉得它会像这样简单:
(defclass my-class () ((a :accessor a :initarg a)))
(defun my-class= (my-instance-1 my-instance-2)
(equal (a my-instance-1) (a my-instance-2)))
(defparameter my-hash-table (make-hash-table :test #'my-class=))
Run Code Online (Sandbox Code Playgroud)
检查Common Lisp Hyperspec,似乎我只能使用eq,eql,equal或equalp来测试相等性.
有什么方法可以做到这一点吗?或者这只是一个真正的stoopid事情,这就是为什么标准不允许它?
我对结构的理解是它有插槽来存储数据,具有类型,具有make-X
和插槽访问器功能,并且可以通过方法专门处理(因为它具有类型).
我对一个类的理解是它具有所有相同和多重继承.这个问题的最佳答案表明结构可以具有单一继承,并且CLOS的初始实现比结构"慢得多".
根据人们如何谈论CLOS和结构,我认为必须存在其他一些差异,但我的琐碎谷歌搜索却毫无结果.所以我问:CLOS和结构之间有什么实际区别?
这种情况一次又一次地发生在我身上:我定义了这个类并忘记了我想要它的功能,或者它是,例如,Gtk小部件类,因此它的元类需要说明.一旦它被定义,但是,SBCL不会让我改变了我的元类(即使没有这个类的实例).例如,评估
(defclass foo ()
((slot-a)))
Run Code Online (Sandbox Code Playgroud)
然后添加元类并重新评估:
(defclass foo ()
((slot-a))
(:metaclass gobject:gobject-class))
Run Code Online (Sandbox Code Playgroud)
导致错误:
Cannot CHANGE-CLASS objects into CLASS metaobjects.
[Condition of type SB-PCL::METAOBJECT-INITIALIZATION-VIOLATION]
See also:
The Art of the Metaobject Protocol, CLASS [:initialization]
Run Code Online (Sandbox Code Playgroud)
不幸的是,我没有"元对象协议的艺术"的副本来检查它的内容.现在我唯一可以解决的方法是重启lisp,这可能会造成很大的破坏性.
由于我很快意识到错误,我不介意通过删除它完全避开已定义的类.问题:
fmakunbound
功能一样的东西.