【问题标题】:Create a polynomial object from a number using change-class使用 change-class 从数字创建多项式对象
【发布时间】:2010-03-28 13:13:56
【问题描述】:

我已经按照 SICP 2.5.3 中描述的方式编写了一个多项式类(使用 defclass 除外)。我希望能够无缝地添加和乘以多项式和常规数字,但我不能让 change-class 接受一个数字。

我试图通过将类从整数更改为浮点数来简化问题:

(change-class 4 'float)

但这给了我错误:

There is no applicable method for the generic function
#<STANDARD-GENERIC-FUNCTION CHANGE-CLASS (7)>
when called with arguments
(4 #<BUILT-IN-CLASS FLOAT>).
[Condition of type SIMPLE-ERROR]

我从 (fyi) 收到相同形式的错误:

(change-class 4 'polynomial)

我将继续执行手动转换,但我更喜欢使用内置的 clos 工具。

正如 Xach 指出的那样,我可以使用强制或浮点数将 4 更改为浮点数。这旨在作为我尝试做的一个更简单的示例,并消除我的 update-instance-for-different-class 错误的任何可能性。

这是我尝试过但不起作用的较长版本:

(defclass polynomial ()
 ((var :accessor var :initarg :var :initform 'x)
  (terms :accessor terms :initarg :terms :initform (make-empty-term-list))))

(defmethod update-instance-for-different-class :before ((old number) 
                        (new polynomial)
                        &key)
    (setf (slot-value new 'terms) (adjoin-term (make-term old 0)
                           (make-empty-term-list))))

(change-class 4 'polynomial)

我仍然收到类似上面示例的错误:

There is no applicable method for the generic function
  #<STANDARD-GENERIC-FUNCTION CHANGE-CLASS (7)>
when called with arguments
  (4 #<STANDARD-CLASS POLYNOMIAL>).
   [Condition of type SIMPLE-ERROR]

【问题讨论】:

    标签: common-lisp sicp sbcl clos


    【解决方案1】:

    您可以使用 COERCE 或 FLOAT 来做到这一点:

    (float 4) => 4.0
    (coerce 4 'float) => 4.0
    

    【讨论】:

    • 嘿 Xach,但我可以使用强制将数字更改为自定义类吗?
    • 没有。你不能在你自己的类的实例上使用普通的 CL 算术函数——它们不是通用函数。
    【解决方案2】:

    您不能对数字使用 CHANGE-CLASS。数字不是 CLOS 类的实例。 CHANGE-CLASS 也被认为破坏性将实例修改为新类,而不更改原始实例的标识。

    我会:

    • 向 CHANGE-CLASS 添加方法来满足您的需求

    • 或编写一个函数 CHANGE,它实现各种自定义强制规则并调用 CHANGE-CLASS 以实现从一个 CLOS 类到另一个 CLOS 类的任何更改。

    【讨论】:

    • 谢谢,我似乎很困惑,因为我记得 cl 一直是对象,但也许它不是 CLOS。我刚刚检查了hyperspec,它说关于t“2.所有对象所属的类型的名称---所有类型的超类型(包括它自己)。3.除了它自己之外的所有类的超类的名称." 也许我会按照这些思路提出一个新问题。
    • @charlieb :请记住,类和类型在 CL 中是两个不同的东西。 CL 还将它的对象分为三类: 1) 内置类,如数字、字符和字符串。 2) 结构和 3) CLOS 实例。 CLOS 允许您为内置类型和结构编写方法,但因此这些仍然不是 CLOS 对象。 CLOS 对象都继承自 STANDARD-OBJECT。例如,数字有一个类 NUMBER,它本身不是一个标准类,而是一个内置类。
    • 我认为部分混淆可能是“对象”这个词。在许多语言中,它的意思是“类的实例”。在 Common Lisp 中,它的意思是“任何 Lisp 数据”——lispworks.com/documentation/HyperSpec/Body/26_glo_o.htm
    • @Ken:对。 Lisp 早于 OOP。通常 Lisp 数据项被称为“对象”,因为可以使用 EQ 功能将它们与其他对象区分开来。 Lisp,甚至是 Common Lisp,都有许多不同的对象系统——例如,“Object Lisp”不是基于类的对象系统,其中对象不是类的实例。 CLOS 已晚添加到 CL。甚至还有非 CLOS 对象的类,例如 number: (find-class 'number) 有效。当一个特别是 STANDARD-CLASS 类的实例并且上下文没有明确说明时,谈论“CLOS 对象”是有道理的。
    猜你喜欢
    • 1970-01-01
    • 2022-01-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多