Lisp常见案例和引用的元素 [英] Common Lisp case and quoted elements

查看:188
本文介绍了Lisp常见案例和引用的元素的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在用CL编写地牢爬虫游戏,但遇到案件表格时遇到了麻烦.

I'm writing a dungeon crawler game in CL, and I'm having trouble with the case form.

两件事:

  • Lisp常见投诉Duplicate keyform QUOTE in CASE statement
  • (make-instance 'cl-rogue:tile tile-type 'wall)应该打印为#",但是无论我使用哪种平铺类型,对象都将打印为".
  • Common Lisp complains Duplicate keyform QUOTE in CASE statement
  • (make-instance 'cl-rogue:tile tile-type 'wall) should print as "#", but the object prints as " " no matter which tile-type I use.

代码:

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

推荐答案

您无需在CASE中引用符号.

不评估CASE子句中的符号.

(case tile-type
  (wall ...)
  (door ...))

WALLDOOR纯粹是符号,不作为变量进行评估.

WALL and DOOR are purely symbols and not evaluated as variables.

Lisp阅读器将'foo读取为(quote foo).

The Lisp reader reads 'fooas (quote foo).

您写道:

(case tile-type
  ('wall ...)
  ('door ...))

相当于:

(case tile-type
  ((quote wall) ...)
  ((quote door) ...))

但是您不能在CASE中引用符号.您必须提供符号作为文字常量.

But you can't quote a symbol in CASE. You have to provide the symbols as literal constants.

如果您写:

(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使用常量数据,而不是变量.

This returns :WE-REALLY-HAVE-A-FOO. Because CASE uses constant data, not variables.

CASE接受项目列表.由于您在more子句中使用QUOTE作为符号,因此编译器显示警告.

CASE accepts a list of items. Since you have QUOTE as a symbol in more than clause, the compiler showed a warning.

正如我所说,由于没有对项目进行评估,因此无法报价.

As I said, there is no quoting possible, since the items are not evaluated.

对于CASE接受子句中的项目列表,它看起来像这样:

As for CASE accepting a list of items in the clauses, it looks like this:

(case tile-type
  ((door wall) ...)
  ((floor window painting) ...))

对于WALL符号,在创建对象时需要确保它在正确的包装中.

For the WALL symbol, you need to make sure that it is in the right package when you create the object.

最好使用关键字符号,例如:wall.然后,您无需导出它,也就不会混淆该符号在哪个包中.

Better use a keyword symbol, such as :wall. Then you don't need to export it and there is no confusion about in which package the symbol is.

关于代码格式: 您有一个项目符号列表,紧随其后的是代码部分.这不会按您期望的方式呈现.我在代码之前添加了文本"The code:".然后,渲染将按预期工作.

About the formatting of the code: You had a bullet list and right after it a code section. This is not rendered as you expect. I have added the text 'The code:' before the code. Then the rendering works as expected.

这篇关于Lisp常见案例和引用的元素的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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