打印读取一致性在 CL 中表示,如果*print-readably*为 true,则打印对象应该:
print-not-readable。相似性的定义稍微复杂,因为它不一定可以在单个图像中定义,因为它的整个目的是允许打印对象,然后在另一个图像中读取对象。它在规范的3.2.4.2中定义,尽管3.2.4的所有内容都值得阅读。特别注意,允许扩展相似性的定义。
请注意,我上面的定义存在一些缺陷:特别是我认为其他打印机和阅读器控制变量需要具有标准值才能*print-readably*有意义(例如*package*,*read-default-float-format*等等。 with-standard-io-syntax是您在这里想要的工具。
最后请注意,在某些情况下,相似性是为同一实现的多个图像定义的。对于标准未定义可读打印表示的对象,允许实现打印内容,以便其自身的另一个实例可以重建类似的对象:它不必确保其他实现可以。
所有这一切意味着,如果您正在定义一个打印对象的机制,那么,如果*print-readably*为真,它应该以读取类似对象的方式打印该对象(可能在相同的实现中),或者发出信号适当的错误:它不应该做的是以不可读的方式悄悄地打印对象,或者以读取表示不会返回类似对象的方式打印对象。做到这一点的一个好方法是使用print-unreadable-object其全部目的是为您确保这一点。
哈希表可能是可读的,也可能不是可读的。在 SBCL 中,它们是:
* (defvar *h* (make-hash-table))
*h*
* (setf (gethash 'foo *h*) 1)
1
* *h*
#<hash-table :TEST eql :COUNT 1 {1002CE5863}>
* (with-standard-io-syntax (print *h*))
#.(SB-IMPL::%STUFF-HASH-TABLE (MAKE-HASH-TABLE) (QUOTE ((FOO . 1))))
#<hash-table :TEST eql :COUNT 1 {1002CE5863}>
Run Code Online (Sandbox Code Playgroud)
#.(...)读取时,该表单将在 SBCL 中重新创建一个类似的哈希表(但仅在 SBCL 中)。
在另一个实现(Clozure CL)中,哈希表不可打印可读:
? (defvar *h* (make-hash-table))
*h*
? (setf (gethash 'foo *h*) 1)
1
? *h*
#<hash-table :test eql size 1/60 #x3020012A119D>
? (with-standard-io-syntax (print *h*))
> Error: Attempt to print object #<HASH-TABLE :TEST EQL size 1/60 #x3020012A119D> on stream #<SYNONYM-STREAM to *TERMINAL-IO* #x302000B9DC1D>
Run Code Online (Sandbox Code Playgroud)