Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Class 使用类的公共Lisp替代方案_Class_Oop_Lisp_Common Lisp_Clos - Fatal编程技术网

Class 使用类的公共Lisp替代方案

Class 使用类的公共Lisp替代方案,class,oop,lisp,common-lisp,clos,Class,Oop,Lisp,Common Lisp,Clos,我想知道如何存储单个变量,并在该变量上具有特定的函数。我想知道是否有其他方法来创建一个类 具体地说,我正在创建一个应用程序,其中我存储一个表示从基准时间(例如,2000年1月1日,00:00:00)经过的秒数的时间值。我希望对此值执行操作,例如将其从秒转换为特定时间或日期,或从日期转换为特定秒 我已经使用一个类完成了这项工作,但是它看起来很浪费。具体地说,每次我访问存储的值经过几秒钟后,它看起来都类似于(time),其中time是时间实例time的访问器 有没有更好的方法来设计它,也许没有类?您

我想知道如何存储单个变量,并在该变量上具有特定的函数。我想知道是否有其他方法来创建一个类

具体地说,我正在创建一个应用程序,其中我存储一个表示从基准时间(例如,2000年1月1日,00:00:00)经过的秒数的时间值。我希望对此值执行操作,例如将其从秒转换为特定时间或日期,或从日期转换为特定秒

我已经使用一个类完成了这项工作,但是它看起来很浪费。具体地说,每次我访问存储的值经过几秒钟后,它看起来都类似于
(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))))