这是我在Hyperspec上看到的一个例子:
(setq fstr (make-array '(0) :element-type 'base-char
:fill-pointer 0 :adjustable t))
(with-output-to-string (s fstr)
(format s "here's some output"))
Run Code Online (Sandbox Code Playgroud)
因此,然后fstr持有here's some output问:你怎么可以做一个简单的清除/重置fstr你想重新开始,把东西在它新的情况,即没有串联多到了吗?或者我只需要重做fstr正在设置的顶级表达式?
设置填充指针:
CL-USER 3 > (setq fstr (make-array '(0) :element-type 'base-char
:fill-pointer 0 :adjustable t))
""
CL-USER 4 > (with-output-to-string (s fstr)
(format s "here's some output"))
NIL
CL-USER 5 > fstr
"here's some output"
CL-USER 6 > (setf (fill-pointer fstr) 0)
0
CL-USER 7 > fstr
""
CL-USER 8 > (with-output-to-string (s fstr)
(format s "here's some more output"))
NIL
CL-USER 9 > fstr
"here's some more output"
Run Code Online (Sandbox Code Playgroud)
您也可以调用adjust-array实际更改数组大小.
CL-USER 16 > (setf (fill-pointer fstr) 0)
0
CL-USER 17 > (adjust-array fstr 0)
""
Run Code Online (Sandbox Code Playgroud)
这里有两个相互作用的正交概念.第一个是矢量(字符串,一维数组等)可以有一个填充指针:
填写指针 ñ.(向量)一个与向量相关联的整数,该向量表示没有元素处于活动状态的索引.(填充指针是一个非负整数,不大于向量中元素的总数.并非所有向量都有填充指针.)
当你正在寻找一个字符串,填充指针本质上是字符串的长度,但可以让底层阵列实际上包含更多的数据(这是仍然可以访问 ;根据不同的应用,这可能是重要的).
然后,有很多方法可以使用填充指针操作向量的内容.对于字符串,有一个有用的字符串,由输出到字符串提供,它创建一个字符输出,将字符输出发送到字符串.
with-output-to-string创建一个字符输出流,执行一系列可以将结果发送到此流的操作,然后关闭该流.
因此,您可以使用(setf fill-pointer) "重置"您的字符串,并且您可以使用with-output-to-string添加内容,以及其他方式:
(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"
)
Run Code Online (Sandbox Code Playgroud)