Class 使用类的公共Lisp替代方案
我想知道如何存储单个变量,并在该变量上具有特定的函数。我想知道是否有其他方法来创建一个类 具体地说,我正在创建一个应用程序,其中我存储一个表示从基准时间(例如,2000年1月1日,00:00:00)经过的秒数的时间值。我希望对此值执行操作,例如将其从秒转换为特定时间或日期,或从日期转换为特定秒 我已经使用一个类完成了这项工作,但是它看起来很浪费。具体地说,每次我访问存储的值经过几秒钟后,它看起来都类似于Class 使用类的公共Lisp替代方案,class,oop,lisp,common-lisp,clos,Class,Oop,Lisp,Common Lisp,Clos,我想知道如何存储单个变量,并在该变量上具有特定的函数。我想知道是否有其他方法来创建一个类 具体地说,我正在创建一个应用程序,其中我存储一个表示从基准时间(例如,2000年1月1日,00:00:00)经过的秒数的时间值。我希望对此值执行操作,例如将其从秒转换为特定时间或日期,或从日期转换为特定秒 我已经使用一个类完成了这项工作,但是它看起来很浪费。具体地说,每次我访问存储的值经过几秒钟后,它看起来都类似于(time),其中time是时间实例time的访问器 有没有更好的方法来设计它,也许没有类?您
(time)
,其中time
是时间实例time
的访问器
有没有更好的方法来设计它,也许没有类?您可以在这样的词法范围内尝试闭包:
(let ((time (get-universal-time)))
(defun set-time(tm)
(setf time tm))
(defun get-time()
time)
(defun get-time-in-some-other-format()
;; calculate return value based on 'time'
)
)
访问器名称 您可以按自己喜欢的方式在CLOS中命名访问器。可以调用访问器函数
seconds
:
CL-USER 23 > (defclass mytime ()
((seconds :accessor seconds :initarg :seconds)))
#<STANDARD-CLASS MYTIME 422015CDD3>
CL-USER 24 > (let ((mt (make-instance 'mytime :seconds 100)))
(values (seconds mt)
(truncate (seconds mt) 60)))
100
1
通过SLOT-VALUE
CLOS还具有通过插槽名称访问插槽的WITH-SLOTS
,这里mytime
实例的secs
插槽可以通过名称secs
访问:
CL-USER 26 > (let ((mt (make-instance 'mytime :seconds 200)))
(with-slots ((secs seconds))
mt
(values secs (truncate secs 60))))
200
3
如果您有一个仅包装单个对象的类,并且该对象具有已知类型,则始终可以只为该对象的类编写方法:
(defmethod time-as-unix-time ((tm integer))
(- tm (load-time-value (encode-universal-time 0 0 0 1 1 1970 0))))
比如说
当然,如果面向对象的狂热者发现你做这种事情,他们会把你扔进一个满是钉子的坑里:这无疑违反了封装或其他邪教的规则。为什么不把它存储为整数呢?说得清楚,你不想使用标准的一部分?按照频率的顺序,你用它做什么?这是一个特定的时间,还是从偏移量开始你就得到了经过的时间?@JoshuaTaylor,我不知道宇宙时间函数。这和我写的东西非常相似。感谢您指出。您可能希望它是
let((time(get universal time)))…)
?这是另一种选择,但它也使您只有一个时间结构实例。这可能会不方便…对不起,错别字,现在已修复。这很漂亮。在此示例之前,我不理解如何在词汇范围上使用闭包。谢谢。我能不能在不使用类的情况下使该方法比按类型更具限制性?@audrow好吧,您使用的是一个类,只是一个。你可以为内置类定义任何类型的方法,你可以为任何其他类定义任何类型的方法:你不能做的是对它进行子类化,它没有任何插槽或其他属性,除了标准为它定义的属性。我明白了。非常感谢。
(defmethod time-as-unix-time ((tm integer))
(- tm (load-time-value (encode-universal-time 0 0 0 1 1 1970 0))))