2013-11-14 3 views
0

я заметил некоторое несоответствие в выходе этого кода в Clisp:только для чтения строк в CLISP

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

Когда я запускаю его из РЕПЛ, я получаю желаемый результат:

[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) при связывании будет исчезнут, когда концы блока?

И, почему несоответствие между двумя выходами?

Наконец, есть ли способ отключить его? Я не считаю предупреждение особенно полезным.

ответ

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:

При попытке изменить данные только для чтения СИГНАЛЫ ОШИБКА. Текст программы и цитируемые константы, загруженные из файлов, считаются данными только для чтения. Эта проверка выполняется только для строк, а не для conses, других видов массивов и пользовательских типов данных.

Это явно разрешено ANSI CL spec:

реализации не требуется обнаруживать попытки модифицировать неизменные объекты или клетки; последствия попытки сделать такие модификации не определены

+0

Су, что проверка не выполняется в реплике? – Segfault

+0

Нет, только в файлах – sds

Смежные вопросы