Common lisp 公共Lisp大小写和引用元素

Common lisp 公共Lisp大小写和引用元素,common-lisp,case,quote,Common Lisp,Case,Quote,我正在用CL写一个地牢爬虫游戏,我在案例表单上遇到了问题 两件事: Common Lisp抱怨CASE语句中存在重复的keyform引号 (使实例'cl rogue:tile tile type'墙)应打印为“#”,但无论使用哪种瓷砖类型,对象都打印为“” 守则: (in-package :cl-user) (defpackage :cl-rogue (:use :common-lisp) (:export :*rows* :*cols* :*levels*

我正在用CL写一个地牢爬虫游戏,我在案例表单上遇到了问题

两件事:

  • Common Lisp抱怨CASE语句中存在重复的keyform引号
  • (使实例'cl rogue:tile tile type'墙)
    应打印为“#”,但无论使用哪种瓷砖类型,对象都打印为“”
守则:

(in-package :cl-user)

(defpackage :cl-rogue
  (:use :common-lisp)
  (:export
    :*rows*
    :*cols*
    :*levels*
    :tile
    :tile-type
    :tile-contents
    :tile-hidden
    :tile-locked
    :tile-closed
    :main))

(in-package :cl-rogue)

(defparameter *cols* 80)
(defparameter *rows* 24)
(defparameter *levels* 26)
班级:

(defclass tile ()
  ((tile-type
    :initarg :tile-type
    :accessor tile-type
    :initform 'floor
    :documentation "Type of tile")
    (tile-contents
      :initarg :tile-contents
      :accessor tile-contents
      :initform '()
      :documentation "Any items the tile holds")
    (tile-hidden
      :initarg :tile-hidden
      :accessor tile-hidden
      :initform nil
      :documentation "Whether the tile is hidden or shown")
    (tile-locked
      :initarg :tile-locked
      :accessor tile-locked
      :initform nil
      :documentation "Whether the tile is locked")
    (tile-closed
      :initarg :tile-closed
      :accessor tile-closed
      :initform nil
      :documentation "Whether the tile is open or closed")))
打印方法:

(defmethod print-object ((object tile) stream)
  (with-slots (tile-type tile-contents tile-hidden tile-locked tile-closed) object
    (if tile-hidden
      (format stream " ")
      (let ((an-item (car tile-contents)))
        (if an-item
          (format stream "~a" an-item)
          (format stream (case tile-type
            ('wall "#")
            ('upstair "<")
            ('downstair ">")
            ('door (if tile-closed "+" "\\"))
            (otherwise " "))))))))
(defmethod打印对象((对象平铺)流)
(带插槽(平铺类型平铺内容平铺隐藏平铺锁定平铺关闭)对象
(如果瓷砖隐藏
(格式化流“”)
(出租((一项(汽车瓷砖内容物)))
(如属项目
(格式化流“~a”项)
(格式化流(案例平铺类型)
(“墙”)
(“楼上”)
(“门”(如果平铺关闭“+”\\”)
(否则为“()()()())()))

您不需要引用
案例中的符号

不计算CASE子句中的符号。

(case tile-type
  (wall ...)
  (door ...))
纯粹是符号,不作为变量计算

Lisp读取器将
'foo
读作
(引用foo)

你写道:

(case tile-type
  ('wall ...)
  ('door ...))
这相当于:

(case tile-type
  ((quote wall) ...)
  ((quote door) ...))
但是您不能在
案例中引用符号。必须将符号作为文字常量提供

如果你写:

(let ((bar 'foo)
      (baz 'foo))
  (case bar
    (baz :we-have-a-foo-through-baz)
    (foo :we-really-have-a-foo)))
这将返回
:WE-REALLY-HAVE-A-FOO
。因为
CASE
使用常量数据,而不是变量

CASE
接受项目列表。由于在多于子句中将
QUOTE
作为符号,编译器显示了一条警告

正如我所说,由于没有对项目进行评估,因此不可能引用

至于
CASE
接受条款中的项目列表,看起来是这样的:

(case tile-type
  ((door wall) ...)
  ((floor window painting) ...))
对于
符号,创建对象时需要确保它位于正确的包中

最好使用关键字符号,例如
:wall
。这样,您就不需要导出它,也就不会混淆符号在哪个包中

关于代码的格式设置
你有一个项目清单,紧接着是代码部分。这并不像您期望的那样呈现。我在代码之前添加了文本“the code:”。然后渲染将按预期工作。

@mcandre:枚举后的代码无法识别。你需要先输入一段文字,然后输入代码。我不知道如何解释。我认为语法是(case-something(this-do-this)(that-do-that)(否则就执行其他操作))这是一个漂亮的答案。