【问题标题】:how understand :print-function in defstruct of common lisp如何理解 :print-function in defstruct of common lisp
【发布时间】:2014-03-04 05:13:52
【问题描述】:

我正在读成功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))

我怎么理解这部分:

(lambda (struct stream depth)
                     (declare (ignore depth))

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

(lambda (struct stream)
         .....)

谢谢

【问题讨论】:

    标签: common-lisp


    【解决方案1】:

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

    (defun foo (bar baz)
      (list bar baz))
    

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

    (foo 'a 'b)     ; correct number of arguments
    => (a b)
    (foo 'a)        ; too few arguments
    => error
    (foo 'a 'b 'c)  ; too many arguments
    => error
    

    由于使用三个参数调用打印机函数 - 对象、流和深度 - 您还必须使用三个参数定义所有打印机。该声明只是通过向编译器指示您有意不使用该参数来删除警告消息。

    【讨论】:

      【解决方案2】:

      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
      

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

      CL-USER 23 > (defun foo (a b)
                     (declare (ignore b))
                     (list a))
      FOO
      

      编译期间没有警告:

      CL-USER 24 > (compile 'foo)
      FOO
      NIL
      NIL
      

      【讨论】:

        猜你喜欢
        • 2020-07-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-09-03
        • 2012-03-09
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多