问题描述
假设我在 Common Lisp 中有一个数字,我想把它转换成一个字符串。至少有三个函数可以将数字转换为字符串:write-to-string
、prin1-to-string
和 princ-to-string
。
据我所知,当用于数字时,所有三个函数都给出相同的结果。真的是这样吗?有没有我应该注意的边缘情况?我应该使用哪个?
解决方法
应该没有区别,但是 WRITE-TO-STRING 有关键字参数。对于与其他两个函数类似的效果,需要在调用周围绑定一个打印机变量。
CL-USER 1 > (write-to-string 12 :base 16)
"C"
CL-USER 2 > (let ((*print-base* 16))
(prin1-to-string 12))
"C"
FORMAT 也可以创建字符串:
CL-USER 3 > (format nil "~16R" 12)
"C"
CL-USER 4 > (format nil "~vR" 16 12)
"C"
,
我认为值得指出的是,在使用任何或所有 write-to-string
、prin1-to-string
、和princ-to-string
。
举个例子:
> (dotimes (i 20)
(print i))
0
1
2
3
4
5
six
seven
eight
IX
X
XI
XII
XIII
XII
XIII
XIII
XIII
XII
XII
nil
这是完全合法的输出,任何符合要求的实现都会产生它(或者实际上是类似的东西,因为涉及一些随机数)。
获取此信息的方法是将 *print-pretty*
设置为 true,然后对 pprint 调度表执行一些有趣的操作。
这可能是潜伏的最大怪物,但还有其他较小的怪物:*print-base*
*print-radix*
其中。
如果您想确保获得的输出是您期望的输出,那么至少您应该用 (with-standard-io-syntax ...)
包围对这些函数的调用。
使用 format
(如在 (format nil "~D" n)
中)更安全(您不再需要关心 *print-base*
和 *print-radix*
之类的东西)但它仍然容易受到环境的影响*print-pretty*
的值,因此与 pprint 调度表的上述游戏。我相信(但不完全确定)
(let ((*print-pretty* nil))
(format nil "~D" 13))
应该返回字符串"13"