Lisp中的只读字符串

时间:2013-11-14 10:31:18

标签: string readonly clisp

我注意到Clisp中此代码的输出存在一些不一致:

(defvar str "Another")
(setf (char str 3) #\!)

当我从repl运行它时,我得到了所需的结果:

[1]> (defvar str "Another")
STR
[2]> (setf (char str 3) #\!)
#\!
[3]> str
"Ano!her"
[4]>

但是,当我从脚本运行它时,我收到有关修改只读字符串的警告:

*** - Attempt to modify a read-only string: "Another"

运行此代码时出现错误:

(print (do ((str "foobar")
            (i 0 (+ i 1)))
           ((= i (length str)) str)
         (setf (char str i) #\!)))

当块结束时绑定将消失时,制作字符串read-only(我假设这与immutable相同)有什么意义?

并且,为什么两个输出之间存在差异?

最后,有没有办法将其关闭?我发现警告并不特别有用。

1 个答案:

答案 0 :(得分:2)

解决方案

首先,您看到的是error,而不是warning

其次,您无法将其关闭,但您可以通过copying不可变字符串来避免它:

(print (do ((str (copy-seq "foobar"))
            (i 0 (+ i 1)))
           ((= i (length str)) str)
         (setf (char str i) #\!)))

动机

Why some data is made immutable是网上讨论的话题。

基本原因是:

  • 多线程环境中的安全性和
  • 更好的编译器

理由

根据the manual

  

尝试修改只读数据SIGNALs ERROR。计划文本和   从文件加载的引用常量被视为只读数据。这个   check仅针对字符串执行,而不是针对conses执行,其他类型   数组和用户定义的数据类型。

ANSI CL spec

明确允许这样做
  

实现不需要检测修改的尝试   不可变对象或单元格;试图制造的后果   这种修改是未定义的