如何理解:普通lisp的defstruct中的print-function

use*_*362 1 common-lisp

我正在读这本书成功的lisp,有一个例子:

(defstruct (ship
              (:print-function
               (lambda (struct stream depth)
                 (declare (ignore depth))
                 (format stream "[ship ~A of ~A at (~D, ~D) moving (~D, ~D)]"
                         (ship-name struct)
                         (ship-player struct)
                         (ship-x-pos struct)
                         (ship-y-pos struct)
                         (ship-x-vel struct)
                         (ship-y-vel struct)))))
    (name "unnamed")
    player
    (x-pos 0.0)
    (y-pos 0.0)
    (x-vel 0.0)
    (y-vel 0.0))
Run Code Online (Sandbox Code Playgroud)

我怎么能理解这部分:

(lambda (struct stream depth)
                     (declare (ignore depth))
Run Code Online (Sandbox Code Playgroud)

为什么要宣布忽略深度?我觉得很困惑,为什么不把lambda写成

(lambda (struct stream)
         .....)
Run Code Online (Sandbox Code Playgroud)

谢谢

jla*_*ahd 5

你不能简单地忽略Common Lisp中的参数 - 例如,javascript.也就是说,如果你写一个函数,如

(defun foo (bar baz)
  (list bar baz))
Run Code Online (Sandbox Code Playgroud)

你不能用任何其他数量的参数调用它:

(foo 'a 'b)     ; correct number of arguments
=> (a b)
(foo 'a)        ; too few arguments
=> error
(foo 'a 'b 'c)  ; too many arguments
=> error
Run Code Online (Sandbox Code Playgroud)

由于使用三个参数(对象,流和深度)调用打印机功能,因此还必须使用三个参数定义所有打印机.声明只是通过向编译器指示您故意不使用参数来删除警告消息.


Rai*_*wig 5

Common Lisp 标准是这样说的:

如果使用 :print-function 选项,那么当要打印结构名称类型的结构时,指定的打印机函数将通过三个参数调用:

  • 要打印的结构(结构名称的通用实例)。
  • 要打印到的流。
  • 指示当前深度的整数。这个整数的大小可能因实现而异;但是,可以可靠地进行比较 *print-level*以确定深度缩写是否合适。

所以它是一个三参数函数。我们需要编写一个带有三个参数的函数。

像往常一样,如果我们的代码没有使用所有参数,我们可以声明它们被忽略,这样编译器就不会打印警告。这里用户没有使用变量depth

示例:在下面的函数中,不清楚是我们忘记使用b还是故意不使用它。

CL-USER 21 > (defun foo (a b)
               (list a))
FOO

CL-USER 22 > (compile 'foo)
;;;*** Warning in FOO: B is bound but not referenced
FOO
Run Code Online (Sandbox Code Playgroud)

现在我们可以告诉编译器我们选择不使用b.

CL-USER 23 > (defun foo (a b)
               (declare (ignore b))
               (list a))
FOO
Run Code Online (Sandbox Code Playgroud)

编译期间没有警告:

CL-USER 24 > (compile 'foo)
FOO
NIL
NIL
Run Code Online (Sandbox Code Playgroud)