如何保护矢量不调整大小?
How to protect vector from resizing?
所以我再次学习 Practical Common Lisp,但我无法真正理解如何创建具有恒定大小的向量。
据书:
However, even a vector with a fill pointer isn't completely resizable. The vector *x* can hold at most five elements. To make an arbitrarily resizable vector, you need to pass MAKE-ARRAY another keyword argument: :adjustable.
然而,当我使用 (vector-push-extend)
时,即使我设置 :adjustable nil
(或保留默认值),我也可以扩展我的初始向量。
(vector-push 'a *x*) ;; 0
(vector-push 'b *x*) ;; 1
(vector-push 'c *x*) ;; 2
(vector-push 'd *x*) ;; 3
(vector-push 'e *x*) ;; 4
*x* ;; #(A B C D E)
(vector-push 'f *x*) ;; NIL
*x* ;; #(A B C D E)
(vector-push-extend 'f *x*) ;; 5
*x* ;; #(A B C D E F)
我假设 (vector-push-extend)
不能调整不是 :adjustable
的数组的大小?创建非动态(不可调整)数组的正确方法是什么?
该行为是特定于实现的。
Common Lisp 规范说:
There is no specified way to create an array for which adjustable-array-p definitely returns false.
即使 make-array
的 :adjustable
参数以 nil
.
形式给出,实现也可能使向量可调
要查看数组对象是否实际上可调,需要调用adjustable-array-p
.
Common Lisp 标准说向量是明确可调的(因此如果被要求的话也是实际可调的。如果不是请求,矢量仍然可以可调,实际可调。
所以 :adjustable nil
arg 只是告诉 Lisp,如果可能的话,它可以使向量不可调整。
在 SBCL 中:
1)法向量不可调整:
* (make-array 5)
#(0 0 0 0 0)
* (adjustable-array-p *)
NIL
2) 带有填充指针的向量在 SBCL 中实际上是可调整的:
* (make-array 5 :fill-pointer 0)
#()
* (adjustable-array-p *)
T
3) 带有填充指针的向量在 SBCL 中 实际上是可调整的,即使 :adjustable
arg 被指定为 nil
:
* (make-array 5 :fill-pointer 0 :adjustable nil)
#()
* (adjustable-array-p *)
T
那是在 SBCL 中。在 LispWorks 中,2) 和 3) 实际上是不可调整的。
make-array
的规范表明,具有 :adjustable nil
的数组是否 实际上是可调整的 取决于实现。在注释中,它继续说:
There is no specified way to create an array for which adjustable-array-p definitely returns false.
所以,这真的取决于实施。
如果不想扩展,正确的方法是使用vector-push
。
所以我再次学习 Practical Common Lisp,但我无法真正理解如何创建具有恒定大小的向量。
据书:
However, even a vector with a fill pointer isn't completely resizable. The vector *x* can hold at most five elements. To make an arbitrarily resizable vector, you need to pass MAKE-ARRAY another keyword argument: :adjustable.
然而,当我使用 (vector-push-extend)
时,即使我设置 :adjustable nil
(或保留默认值),我也可以扩展我的初始向量。
(vector-push 'a *x*) ;; 0
(vector-push 'b *x*) ;; 1
(vector-push 'c *x*) ;; 2
(vector-push 'd *x*) ;; 3
(vector-push 'e *x*) ;; 4
*x* ;; #(A B C D E)
(vector-push 'f *x*) ;; NIL
*x* ;; #(A B C D E)
(vector-push-extend 'f *x*) ;; 5
*x* ;; #(A B C D E F)
我假设 (vector-push-extend)
不能调整不是 :adjustable
的数组的大小?创建非动态(不可调整)数组的正确方法是什么?
该行为是特定于实现的。
Common Lisp 规范说:
There is no specified way to create an array for which adjustable-array-p definitely returns false.
即使 make-array
的 :adjustable
参数以 nil
.
要查看数组对象是否实际上可调,需要调用adjustable-array-p
.
Common Lisp 标准说向量是明确可调的(因此如果被要求的话也是实际可调的。如果不是请求,矢量仍然可以可调,实际可调。
所以 :adjustable nil
arg 只是告诉 Lisp,如果可能的话,它可以使向量不可调整。
在 SBCL 中:
1)法向量不可调整:
* (make-array 5)
#(0 0 0 0 0)
* (adjustable-array-p *)
NIL
2) 带有填充指针的向量在 SBCL 中实际上是可调整的:
* (make-array 5 :fill-pointer 0)
#()
* (adjustable-array-p *)
T
3) 带有填充指针的向量在 SBCL 中 实际上是可调整的,即使 :adjustable
arg 被指定为 nil
:
* (make-array 5 :fill-pointer 0 :adjustable nil)
#()
* (adjustable-array-p *)
T
那是在 SBCL 中。在 LispWorks 中,2) 和 3) 实际上是不可调整的。
make-array
的规范表明,具有 :adjustable nil
的数组是否 实际上是可调整的 取决于实现。在注释中,它继续说:
There is no specified way to create an array for which adjustable-array-p definitely returns false.
所以,这真的取决于实施。
如果不想扩展,正确的方法是使用vector-push
。