Здесь взаимодействуют две ортогональные концепции. Во-первых, что векторы (строки, одномерные массивы и т.д.) могут иметь fill pointer:
указатель заполнения п. (вектора) целое число, ассоциированное с вектором, которое представляет собой индекс, над которым нет активных элементов. (Указатель заполнения не является неотрицательным целым числом не больше, чем общее число элементов в векторе. Не все векторы имеют заполнять указатели.)
Когда вы смотрите на строку, указатель заполнения по существу длина строки, но позволяет основному массиву фактически содержать больше данных (, который равен, все еще доступен; это может быть важно в зависимости от приложения).
Затем существует множество способов управления содержимым вектора с помощью указателя заполнения. Для строк есть полезный, предоставляемый with-output-to-string, который создает пар символов, который отправляет вывод символов в строку.
с-вывода в строку создает выходной поток символов, выполняет ряд операций, которые могут посылать результаты к этому потоку, и затем закрывает поток.
Таким образом, вы можете «сбросить» вашу строку с (setf fill-pointer), и вы можете добавить контент с с-вывода в строку, среди прочего:
(let ((str (make-array '(0)
:element-type 'base-char
:adjustable t
:fill-pointer 0)))
;; Temporarily create a character output stream that directs its
;; output to the underlying string that we created, and write "hello
;; world!" to it.
(with-output-to-string (s str)
(format s "hello world!"))
;; prints "hello world", sets the FILL-POINTER back to 0, and then
;; prints "".
(print str)
(setf (fill-pointer str) 0)
(print str)
;; But note that the underlying array
;; and the content that you put into
;; it are still available. While LENGTH
;; returns 0, ARRAY-TOTAL-SIZE reports
;; 12, and you can still just AREF to
;; get the old content.
(print (length str)) ;=> 0
(print (array-total-size str)) ;=> 12
(print (aref str 6)) ;=> #\w
;; update content using vector push extend, and print "abcde".
(vector-push-extend #\a str)
(vector-push-extend #\b str)
(vector-push-extend #\c str)
(vector-push-extend #\d str)
(vector-push-extend #\e str)
(print str) ;=> "abcde"
;; Or set the fill pointer manually, possibly setting content in the
;; array before or after. Note that you can (SETF AREF) elements in
;; the vector that aren't in the active portion. First, we confirm
;; that the fill pointer is at 5, then set an element at 8 (past the
;; fill pointer), then set the fill pointer to 10, and set an
;; element at 6 (before the fill pointer). All these changes affect
;; the vector contents.
(print (fill-pointer str)) ;=> 5
(setf (aref str 8) #\X)
(setf (fill-pointer str) 10)
(setf (aref str 6) #\Y)
(print str) ;=> "abcde YoXl"
)
просто уточнить, нет никаких * ввод * поток здесь. Существует массив (который также является строкой из-за своего типа элемента), который имеет указатель заполнения. ** with-output-to-string ** создает поток символов * output *, который отправляет свой вывод в строку. –