Lisp为什么我的对象是同一实例?

时间:2018-08-23 20:22:20

标签: arrays lisp common-lisp

因此,我想重新制作一个使用列表包含对象的程序,并将列表替换为数组。

然后我遇到了一个问题,即我的对象属于同一实例

(setq arr (make-array 3 :initial-element (make-instance 'object) :adjustable t :fill-pointer 3))

执行此代码后

数组中的所有对象都相同 口译员给了我

#(#<OBJECT {1002DFDD23}> #<OBJECT {1002DFDD23}> #<OBJECT {1002DFDD23}>)

我知道执行此操作的其他方法,但仍然想知道为什么会发生这种情况?

如果没有问题,#<OBJECT {1002DFDD23}的整体含义是什么?这是某种内存地址吗?

3 个答案:

答案 0 :(得分:5)

(make-instance 'object)表单在调用代码时仅被评估一次。结果用作数组中每个元素的初始值。可能会看到单字initial-element(不是-elements)会有所帮助,而且以make-开头的运算符通常是函数,因此所有参数都在调用之前进行求值。

输出#<OBJECT {1002DFDD23}>用于不可读的对象。这由#<语法表示,该语法定义为在尝试read时发出错误信号(http://clhs.lisp.se/Body/02_dht.htm)。它通常由print-unreadable-object产生,通常在为print-object定义方法时使用。因此,确切的输出是实现或用户定义的(为该特定类编写了print-object方法的人)。默认情况下,它将最有可能包含类名称以及诸如内存引用或地址之类的内容。

为了完整起见,我喜欢使用map-into

(map-into (make-array 3 :adjustable t :fill-pointer 3)
          (lambda () (make-instance 'object)))

获取使用不同对象初始化的数组。

答案 1 :(得分:4)

make-array是一个函数。在调用之前先评估其参数。

以下等同:

(make-array 3
            :initial-element (make-instance 'object)
            :adjustable t
            :fill-pointer 3))

(let ((a 3)
      (b :initial-element)
      (c (make-instance 'object))
      (d :adjustable)
      (e t)
      (f :fill-pointer)
      (g 3))
  (make-array a b c d e f g))

答案 2 :(得分:2)

Common Lisp HyperSpec: Function MAKE-ARRAY

  

如果提供了initial-element,它将用于初始化new-array的每个元素