在定义print-object
方法时,它有多重要?
例如,在我看来,SBCL中的hash-table
实例违反了这个原则。
发布于 2022-01-21 09:08:03
在CL中,打印-读一致性表示,如果*print-readably*
是真的,那么打印对象应该是:
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}>
#.(...)
表单在读取时将重新创建一个类似的散列表(但仅在SBCL中)。
在另一个实现(Clozure )中,哈希表无法可读地打印:
? (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>
https://stackoverflow.com/questions/70797208
复制相似问题