我必须编写一个面向对象的计数器。首先,函数make-object应该用内部状态0实例化对象a和b。然后调用'methods':inc,:dec和:res(增加,减少,重置)。它应该是这样的:
> (setq a (make-object) b (make-object))
...
> (funcall a :inc)
1
> (funcall a :inc)
2
> (funcall a :res)
0
> (funcall a :dec)
-1
> (funcall b :inc)
1
到目前为止我的解决方案看起来像这样:
(defun make-object ()
(let ((counter 0))
(list #'(lambda () (incf counter))
#'(lambda () (setf counter 0))
#'(lambda () (decf counter)))))
使用
(setq a (make-object) b (make-object))
我可以实例化a和b,并使用
调用这些方法(funcall (first a))
(funcall (second b))
(funcall (third a))
我尝试使用“:inc”而不是“first”调用方法:
(defun myfuncall (var fun)
(funcall ((cond ((equal fun ":inc") first)
((equal fun ":res") second)
((equal fun ":dec") third))
var)))
但是有错误
While compiling MYFUNCALL :
In the form (#1=(COND ((EQUAL FUN ":inc") FIRST)
((EQUAL FUN ":res") SECOND)
((EQUAL FUN ":dec") THIRD))
VAR), #1# is not a symbol or lambda expression.
[Condition of type CCL::COMPILE-TIME-PROGRAM-ERROR]
有人能帮帮我吗?如何让funcall为我做正确的事?
找到了解决方案。
(defun make-object ()
(let ((count 0))
(lambda (msg)
(case msg
((:inc) (incf count))
((:dec) (decf count))
((:res) (setq count 0))))))
这就是我想要的。
答案 0 :(得分:3)
这几乎正常。
(defun myfuncall (var fun)
(funcall ((cond ((equal fun ":inc") first)
((equal fun ":res") second)
((equal fun ":dec") third))
var)))
( ... )
和COND
表单附加var
。你需要删除它。
first
(等)也是变量引用。您需要致电(first var)
。
一旦你开始工作,你可能想要以不同的方式编写代码。如果MAKE-OBJECT
将返回单个函数而不是三个函数列表,该怎么办?怎么可能有用?
下一个问题
((equal fun ":inc") 'first var)
上面没有意义。您想在FIRST
的结果上调用函数var
。然后,这将返回一个函数,然后通过FUNCALL
调用该函数。