У вас есть правильный диагноз. Это даже не вопрос буквальных данных (например, (list 1 2 3)
против '(1 2 3)
), а также модифицируемых данных. Это то, имеет ли вектор fill pointer. В документации для vector-push
and vector-push-extend
говорится, что аргумент является вектором с указателем заполнения. Вы получите подобную ошибку с небуквальными массивами, которые не имеют указателя заполнения, например:
(let ((v (make-array 3)))
(vector-push nil v))
Все, что вам нужно сделать, это убедиться, что вы создаете вектор с указателем заполнения, и что он достаточно большой, чтобы держать вещи, которые вы толкаете в:
(let ((v (make-array 2 :fill-pointer 0)))
(print v)
(vector-push 'x v)
(print v)
(vector-push 'y v)
(print v)
(vector-push 'z v)
(print v))
vector-push
не регулирует массив, так что вы получите не z
в векторе из конечного vector-push
:
#()
#(X)
#(X Y)
#(X Y)
Если вы вектор регулирует, и использовать vector-push-extend
, вы можете получить больший массив:
(let ((v (make-array 2 :adjustable t :fill-pointer 0)))
(print v)
(vector-push 'x v)
(print v)
(vector-push 'y v)
(print v)
(vector-push-extend 'z v)
(print v))
#()
#(X)
#(X Y)
#(X Y Z)
Используя тип элемента character
, вы будете делать это со строками:
(let ((v (make-array 2 :element-type 'character :adjustable t :fill-pointer 0)))
(print v)
(vector-push #\x v)
(print v)
(vector-push #\y v)
(print v)
(vector-push-extend #\z v)
(print v))
""
"x"
"xy"
"xyz"
One вопрос, почему вы помещаете символ @ char в качестве начального элемента. (char-code # \ @) -> 64, который является кодовым пунктом для символа literal @. – PuercoPop
@PuercoPop Мои первые примеры включали исходные элементы, поэтому в интересах изменения как можно меньше я использовал начальный элемент в примере строки. Тем не менее, SBCL сигнализирует об ошибке, если начальный элемент для строки не является символом, поэтому я использовал символ, который так и был «# \ @». Однако ни один из этих примеров не нуждается в исходных элементах, поэтому я удалил их из примеров. –