如何用填充指针清除字符串?
How to clear string with fill pointer?
这是我在 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"))
那么 fstr
持有 here's some output
问:如果您想重新开始并放入一些新东西,您如何在 fstr
上做一个简单的 clear/reset它,也就是说,不连接更多吗?还是我只需要重做正在设置 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"
您也可以调用 adjust-array
实际更改数组大小。
CL-USER 16 > (setf (fill-pointer fstr) 0)
0
CL-USER 17 > (adjust-array fstr 0)
""
这里有两个正交的概念在相互作用。第一个是向量(字符串、一维数组等)可以有一个 fill pointer:
fill pointer n. (of a vector) an integer associated with a vector that
represents the index above which no elements are active. (A fill
pointer is a non-negative integer no larger than the total number of
elements in the vector. Not all vectors have fill pointers.)
当您查看字符串时,填充指针本质上是字符串的长度,但允许底层数组实际包含更多数据(其中是 仍然可以访问;这可能很重要,具体取决于应用程序)。
然后,有很多方法可以使用填充指针来操作向量的内容。对于 strings,with-output-to-string 提供了一个有用的方法,它创建一个字符流,将字符输出发送到字符串。
with-output-to-string creates a character output stream, performs a series of operations that may send results to this stream, and then
closes the stream.
因此,您可以使用 (setf fill-pointer) "reset" 您的字符串,您可以使用 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"
)
这是我在 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"))
那么 fstr
持有 here's some output
问:如果您想重新开始并放入一些新东西,您如何在 fstr
上做一个简单的 clear/reset它,也就是说,不连接更多吗?还是我只需要重做正在设置 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"
您也可以调用 adjust-array
实际更改数组大小。
CL-USER 16 > (setf (fill-pointer fstr) 0)
0
CL-USER 17 > (adjust-array fstr 0)
""
这里有两个正交的概念在相互作用。第一个是向量(字符串、一维数组等)可以有一个 fill pointer:
fill pointer n. (of a vector) an integer associated with a vector that represents the index above which no elements are active. (A fill pointer is a non-negative integer no larger than the total number of elements in the vector. Not all vectors have fill pointers.)
当您查看字符串时,填充指针本质上是字符串的长度,但允许底层数组实际包含更多数据(其中是 仍然可以访问;这可能很重要,具体取决于应用程序)。
然后,有很多方法可以使用填充指针来操作向量的内容。对于 strings,with-output-to-string 提供了一个有用的方法,它创建一个字符流,将字符输出发送到字符串。
with-output-to-string creates a character output stream, performs a series of operations that may send results to this stream, and then closes the stream.
因此,您可以使用 (setf fill-pointer) "reset" 您的字符串,您可以使用 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"
)