对于我的项目,我特别需要一个具有(其中包括)2个插槽的结构:
该功能槽必须评估当前状态并根据它返回结果。但是,我无法找到如何正确地做到这一点。这是我的代码的一部分。
(defstruct state moves-left)
(defstruct problem
(current-state)
(solution (function (lambda () (null (state-moves-left :current-state)))))
)
编译时没有错误,但是当我解释它时会发生错误:
> (setq p0 (make-problem :current-state (make-state)))
> (funcall (problem-solution p0))
SYSTEM::%STRUCTURE-REF: :CURRENT-STATE is not a structure of type STATE
任何人都知道如何解决这个问题?我通常只使用常用功能,但这些结构和插槽都是硬性要求。
编辑:谢谢你的回答。在得知这是不可能的之后,我更彻底地重新阅读了这些要求,并发现这个函数实际上会得到一个参数(一个状态)。所以,代码现在有效:(defstruct problem
(current-state)
(solution (function (lambda (state) (not (null (state-moves-left state))))))
)
答案 0 :(得分:4)
您可以拥有单独的创建功能:
(defun create-problem (state)
(let ((problem (make-problem :current-state state)))
(setf (problem-solution problem)
(lambda ()
(null (state-moves-left (problem-current-state problem)))))
problem))
但是:为什么不直接使用函数/方法?
(defmethod problem-solution ((p problem))
(null (state-moves-left (problem-current-state p))))
答案 1 :(得分:2)
错误的原因是Common Lisp中的结构不能用作类:在插槽solution
的函数默认值内部,无法引用结构本身的插槽(因为你是尝试使用(state-moves-left :current-state)
。
如果你坚持使用结构而不是类,一种可能性是用参数定义函数,并在调用函数时传递结构本身。类似的东西:
(defstruct problem
(current-state)
(solution (function (lambda (p) (null (state-moves-left p))))))
(let ((p0 (make-problem :current-state (make-state))))
(funcall (problem-solution p0) p0))
答案 2 :(得分:0)
在了解到这是不可能的之后,我更彻底地重读了需求,发现这个函数实际上会接收一个参数(一个状态)。所以,代码现在可以工作了:
(解构问题 (当前状态) (解决方案(函数(lambda(状态)(不是(空(状态-移动-左状态)))))) )