Common lisp 从泛型方法返回实例列表
我需要在通用方法中返回矩形的坐标列表。坐标是一个类“cart”实例 我尝试用make实例返回它Common lisp 从泛型方法返回实例列表,common-lisp,evaluation,quote,Common Lisp,Evaluation,Quote,我需要在通用方法中返回矩形的坐标列表。坐标是一个类“cart”实例 我尝试用make实例返回它 (定义类行() ((开始:initarg:start:accessor行开始) (end:initarg:end:accessor行结束))) (defmethod打印对象((lin行)流) (格式化流“[LINE~s~s]” (线路起点lin)(线路终点lin))) (defclass cart() ((x:initarg:x:reader cart-x) (y:initarg:y:reader c
(定义类行()
((开始:initarg:start:accessor行开始)
(end:initarg:end:accessor行结束)))
(defmethod打印对象((lin行)流)
(格式化流“[LINE~s~s]”
(线路起点lin)(线路终点lin)))
(defclass cart()
((x:initarg:x:reader cart-x)
(y:initarg:y:reader cart-y)))
(defmethod打印对象((c cart)流)
(格式化流“[CART x~d y~d]”
(购物车x c)(购物车y c)))
(setq lin(生成实例)行
:开始(生成实例的购物车:x 4:y 3)
:end(生成实例“购物车:x 7:y 5)))
(反泛型包含矩形(形状))
(defmethod包含rect((l行))
(让((x1(小车-x(线路起点l)))
(y1(小车y(线路起点l)))
(x2(车-x(线端l)))
(y2(大车-y(线路端l)))
(cond(=x1 x2)
((生成实例)购物车:x(1-x1):y y1)
(使实例的购物车:x(1+x1):y y1)
(使实例的购物车:x(1-x2):y y2)
(使实例“购物车:x(1+x2):y y2)))
(=y1 y2)
“((生成实例”购物车:x x1:y(1-y1))
(制作实例“购物车:x x1:y(1+y1))
(制作实例“购物车:x x2:y(1-y2))
(使实例“购物车:x x2:y(1+y2)))
(t
(rect'((make-instance'cart:x x1:y y1)
(使实例'购物车:x x1:y y2)
(使实例的购物车:x x2:y y2)
(使实例'cart:x2:yy1()()()()))
(印刷品(含直读林))
我想makeinstance
应该为某个对象分配一个实例
所以我得到了错误的结果
((MAKE-INSTANCE'购物车:X X1:Y Y1)(MAKE-INSTANCE'购物车:X X1:Y Y2)
(MAKE-INSTANCE'购物车:X X2:Y Y2)(MAKE-INSTANCE'购物车:X X2:Y Y1))
但我需要这样的输出
([CART x 4 y 3][CART x 4 y 3][CART x 4 y 3][CART x 4 y 3][CART x 4 y 3])
如果你引用某个东西,它不会被评估
这:
是一个由四个文本列表组成的文本列表,每个列表以符号MAKE-INSTANCE
开头,然后有一个列表(报价车)
,等等。这正是您看到的结果
你似乎想实际评估一下。最简单的方法是这样做并列出一个清单:
(list (make-instance 'cart :x (1- x1) :y y1)
(make-instance 'cart :x (1+ x1) :y y1)
(make-instance 'cart :x (1- x2) :y y2)
(make-instance 'cart :x (1+ x2) :y y2))
这与引用某些内容有着根本的不同。关于代码的一些附加提示 班级 这不是硬性规定,但访问器函数(属于通用函数)通常仅以插槽命名,即
x
,而不是get-x
(绝对是“坏”样式)或object-x
(不坏,仍然很常见)
我不知道你的要求是什么,所以我发明了一些;特别是,我将矩形表示为2个点(左上角和右下角)
构造函数
拥有构造函数有助于获得简洁易读的代码:
(defun cart (x y)
(make-instance 'cart :x x :y y))
(defun line (start end)
(make-instance 'line :start start :end end))
对于矩形,首先对点进行排序,以构建左上角和右下角点
(defun sorted-coordinate (points coordinate)
(sort (mapcar coordinate points) #'<))
(defun rect (point-1 point-2)
(let ((points (list point-1 point-2)))
(destructuring-bind (low-x high-x) (sorted-coordinate points #'x)
(destructuring-bind (low-y high-y) (sorted-coordinate points #'y)
(make-instance 'rect
:upper-left (cart low-x high-y)
:bottom-right (cart high-x low-y))))))
例子
然后,对结果线进行评估,得出:
CL-USER> *TEST-LINE*
=> (LINE (CART 4 3) (CART 7 5))
上面这是一个由REPL打印的值,它正是用来构建它的表达式
矩形形状的边界
通用函数要简单得多(但可能是错误的,因为矩形的处理方式不同):
例如:
CL-USER> (containing-rect *test-line*)
=> (RECT (CART 4 5) (CART 7 3))
为什么不调用
lin
变量行
?
(defmethod print-object ((line line) stream)
(prin1 `(line ,(start line) ,(end line)) stream))
(defmethod print-object ((c cart) stream)
(prin1 `(cart ,(x c) ,(y c)) stream))
(defmethod print-object ((rect rect) stream)
(prin1 `(rect ,(upper-left rect) ,(bottom-right rect)) stream))
(defparameter *test-line*
(line (cart 4 3) (cart 7 5)))
CL-USER> *TEST-LINE*
=> (LINE (CART 4 3) (CART 7 5))
(defgeneric containing-rect (shape))
(defmethod containing-rect ((line line))
(rect (start line) (end line)))
CL-USER> (containing-rect *test-line*)
=> (RECT (CART 4 5) (CART 7 3))