Common Lisp:将对象传递给方法 [英] Common Lisp: Passing an object to a method

查看:111
本文介绍了Common Lisp:将对象传递给方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对对象(类实例)的行为有疑问。

I have a problem with the behaviour of objects (class instances).

代码示例:

(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))

当某工作与参数列表中的游戏卡对象一起使用时,

When some-job is used with a game-cards object in the parameter list, it works like I expected.

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]

当我将some-job定义为函数时:

When I define some-job as a function:

(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 * 不能通过某些工作和肤色来区分为游戏卡的实例。

It seems that *king-hearts* is now not distinguished as an instance of game-cards by some-job and colour.

原因是什么?

推荐答案

不评估报价数据。这是Lisp的基本评估规则:

Quoted data is not evaluated. That's a basic Lisp evaluation rule:

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 是符号而不是数字:

Here PI is a symbol and not a number:

CL-USER 6 > (type-of 'pi)
SYMBOL

CL-USER 7 > (type-of pi)
DOUBLE-FLOAT

因此我们可以为a定义方法数字:

Thus we can define a method for a number:

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.

我们可以在调试器中为符号定义方法:

We can define a method for a symbol in the debugger:

CL-USER 11 : 1 > (defmethod square ((n symbol))
                   (let ((n (symbol-value n)))
                     (* n n)))
#<STANDARD-METHOD SQUARE NIL (SYMBOL) 4020285ED3>

然后我们重新调用该呼叫:

And then we re-invoke the call:

CL-USER 12 : 1 > :c 1
9.869604401089358D0

如何解决您的问题:


  • 要么使用 LIST
  • $创建CLOS对象列表b $ b
  • 或使用 SYMBOL-VALUE 从全局变量中检索CLOS对象。

  • Either create a list of CLOS objects using LIST
  • or retrieve the CLOS objects from the global variable using SYMBOL-VALUE.

后者通常没什么意义。

这篇关于Common Lisp:将对象传递给方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆