我注意到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
相同)有什么意义?
并且,为什么两个输出之间存在差异?
最后,有没有办法将其关闭?我发现警告并不特别有用。
答案 0 :(得分:2)
其次,您无法将其关闭,但您可以通过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执行,其他类型 数组和用户定义的数据类型。
实现不需要检测修改的尝试 不可变对象或单元格;试图制造的后果 这种修改是未定义的