我对象(类实例)的行为有问题。
代码示例:
(defclass game-cards ()
((card-symbol :initarg :card-symbol :accessor card-symbol)
(colour :initarg :colour :accessor colour)))
(defvar *king-hearts* (make-instance 'game-cards
:card-symbol 'King
:colour 'hearts))
(defvar *ace-spades* (make-instance 'game-cards
:card-symbol 'Ace
:colour 'spades))
(defclass game-states ()
((my-cards :initarg :my-cards :accessor my-cards)
(other-cards :initarg :other-cards :accessor other-cards)))
(defparameter *state-1*
(make-instance 'game-states
:my-cards '(*king-hearts* *ace-spades*)
:other-cards ()))
(defmethod play-game ((state game-states))
(some-job (first (my-cards state))))
(defmethod some-job ((card game-cards))
(colour card))
当某个作业与参数列表中的游戏卡对象一起使用时,它会像我预期的那样工作。
CL-USER> (some-job *king-hearts*)
HEARTS
CL-USER>
这也有效:
CL-USER> (first (my-cards *state-1*))
*KING-HEARTS*
CL-USER>
当我尝试这个时:
(some-job (first (my-cards *state-1*)))
我收到以下错误消息:
There is no applicable method for the generic function
#<STANDARD-GENERIC-FUNCTION COMMON-LISP-USER::SOME-JOB (1)>
when called with arguments
(*KING-HEARTS*).
[Condition of type SIMPLE-ERROR]
当我将某个作业定义为函数时:
(defun some-job-1 (card)
(colour card))
发生同样的行为。
现在出现错误消息:
There is no applicable method for the generic function
#<STANDARD-GENERIC-FUNCTION COMMON-LISP-USER::COLOUR (1)>
when called with arguments
(*KING-HEARTS*).
[Condition of type SIMPLE-ERROR]
似乎*king-hearts*
现在没有通过某种工作和颜色区分为游戏卡的实例。
是什么原因?坦克你的答案。
答案 0 :(得分:2)
不评估引用数据。这是一个基本的Lisp评估规则:
CL-USER 1 > pi
3.141592653589793D0
CL-USER 2 > 'pi
PI
CL-USER 3 > '(pi pi)
(PI PI)
CL-USER 4 > (list pi pi)
(3.141592653589793D0 3.141592653589793D0)
CL-USER 5 > (list 'pi 'pi)
(PI PI)
此处PI
是符号,而不是数字:
CL-USER 6 > (type-of 'pi)
SYMBOL
CL-USER 7 > (type-of pi)
DOUBLE-FLOAT
因此我们可以为数字定义一个方法:
CL-USER 8 > (defmethod square ((n number)) (* n n))
#<STANDARD-METHOD SQUARE NIL (NUMBER) 402005F60B>
CL-USER 9 > (square pi)
9.869604401089358D0
但是对符号的调用不起作用,因为只有一个数字的方法:
CL-USER 10 > (square 'pi)
Error: No applicable methods for #<STANDARD-GENERIC-FUNCTION SQUARE 4060010C1C> with args (PI)
1 (continue) Call #<STANDARD-GENERIC-FUNCTION SQUARE 4060010C1C> again
2 (abort) Return to top loop level 0.
Type :b for backtrace or :c <option number> to proceed.
Type :bug-form "<subject>" for a bug report template or :? for other options.
我们可以在调试器中为符号定义一个方法:
CL-USER 11 : 1 > (defmethod square ((n symbol))
(let ((n (symbol-value n)))
(* n n)))
#<STANDARD-METHOD SQUARE NIL (SYMBOL) 4020285ED3>
然后我们重新调用这个电话:
CL-USER 12 : 1 > :c 1
9.869604401089358D0
如何解决问题:
LIST
SYMBOL-VALUE
从全局变量中检索CLOS对象。后者通常没什么意义。