2015-02-23 57 views
1

我想在Common Lisp中使用用其文本元素初始化的SBCL創建一個節點對象,然後鏈接到其他節點。我的功能鏈接應該採用節點「from_node」,獲取其成員鏈接(應該是一個可變/可擴展的向量),並將節點推入「to_node」。這個lisp向量爲什麼不擴展?

我編譯say.lisp,創建2個代表節點的全局變量,然後嘗試鏈接兩個節點。我得到一個錯誤

這裏是say.lisp

(defclass node() 
    ((text 
    :initarg :text) 
    (links 
    :initform (make-array 1 :adjustable t)))) 

(defun link (from_node to_node) 
    (vector-push-extend to_node (slot-value from_node 'links))) 

然後在REPL

* (load "say.lisp") 
T 
* (defvar *x* (make-instance 'node :text "hello world")) 

*X* 
* (defvar *y* (make-instance 'node :text "bye world")) 

*Y* 
* (link *x* *y*) 

debugger invoked on a TYPE-ERROR in thread 
#<THREAD "main thread" RUNNING {1003016593}>: 
    The value #() is not of type (AND VECTOR (NOT SIMPLE-ARRAY)). 

Type HELP for debugger help, or (SB-EXT:EXIT) to exit from SBCL. 

restarts (invokable by number or by possibly-abbreviated name): 
    0: [ABORT] Exit debugger, returning to top level. 

(VECTOR-PUSH-EXTEND #<NODE {10031D3983}> #() NIL) 
0] 

原本我以爲我正在一個不變的載體,但「:可調節T」應該允許這個工作。

出了什麼問題?

回答

3

VECTOR-PUSH-EXTEND要求vector參數是一個「帶有填充指針的向量」。通過:可調tmake-array使其可調,但不給它一個填充指針。例如,沒有填充指針:

CL-USER> (defparameter *x* (make-array 1 :adjustable t)) 
*X* 
CL-USER> *x* 
#(0) 
CL-USER> (vector-push-extend 3 *x*) 
; Evaluation aborted on #<SIMPLE-TYPE-ERROR expected-type: 
        (AND VECTOR (SATISFIES ARRAY-HAS-FILL-POINTER-P)) 
        datum: #<(VECTOR T 1) {100464C57F}>>. 

了補指針:

CL-USER> (defparameter *x* (make-array 1 :adjustable t :fill-pointer 0)) 
*X* 
CL-USER> *x* 
#() 
CL-USER> (vector-push-extend 3 *x*) 
0 
CL-USER> (vector-push-extend 4 *x*) 
1 
CL-USER> (vector-push-extend 5 *x*) 
2 
CL-USER> *x* 
#(3 4 5) 

這是一個重要的區別,因爲你可以有可調數組不填充指針,如您所見。這些可以調整大小,但總是看起來像空間一樣多。 (例如,在第一種情況下,* X *具有長度之一。你也可以有陣列將填補是不可調的指針。這將仍然允許您使用載體推動矢量推延長直到它們被填滿,但之後無法調整大小

+0

謝謝,函數沒有「下一個填充位置」 – SlightlyCyborg 2015-02-23 19:34:32

相關問題