读取SBCL中带有类型插槽的结构

Wer*_*dok 4 lisp arrays sbcl common-lisp read-eval-print-loop

考虑这个简单的代码示例:

(defstruct test
  (:example nil :type (simple-array single-float)))

(defparameter test-struct
  (make-test :example (make-array 10 :element-type 'single-float
                                     :initial-element 1.0)))
Run Code Online (Sandbox Code Playgroud)

我们可以看到,没有什么可以疯狂的,定义了一个带有单个槽的简单结构.我们还指定:example插槽是强类型,预期是单个浮点数组.这里没有问题,一切正常.

我们test-struct现在写一个文件:

(with-open-file (out "~/Desktop/out.test"
             :direction :output
             :if-exists :supersede)
  (format out "~s" test-struct))
Run Code Online (Sandbox Code Playgroud)

同样,没有惊喜,我们在桌面上获得一个漂亮的小文件,其中包含以下内容:

#S(TEST :EXAMPLE #(1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0))
Run Code Online (Sandbox Code Playgroud)

然而,紧张开始蔓延,因为我们注意到没有任何迹象表明这个特定的文字数组应该包含单个浮点数.有了这种怀疑,让我们尝试加载这个结构:

(defparameter loaded-struct
  (with-open-file (in "~/Desktop/out.test")
    (read in nil)))
Run Code Online (Sandbox Code Playgroud)

我们在这里,SBCL愉快地将我们放入调试器:

尝试读取类型化数组时,SBCL会进入调试器

问题是:有没有办法指示SBCL验证结构中的这个数组插槽是否是有效类型并加载它?或者换句话说,是否可以在不诉诸构建自定义编写器和构造函数的情况下读取具有强类型插槽的结构?

cor*_*ump 7

如果您可读地打印对象,它可以工作:

(equalp test-struct
        (read-from-string 
          (with-output-to-string (o)
            (write test-struct :readably t :stream o))))
=> T ;; no error while reading the structure back
Run Code Online (Sandbox Code Playgroud)

字符串是:

"#S(TEST
   :EXAMPLE #.(COERCE #(1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0)
                      '(SIMPLE-ARRAY SINGLE-FLOAT (*))))"
Run Code Online (Sandbox Code Playgroud)

如果你想使用format,使用~W*print-readably*是T.