Незамеченные символы в основном используются в качестве имен или обозначений, чтобы избежать загромождения пакетов или для связанных задач.
Например:
T1> (find-symbol "T2")
NIL
NIL
T1> (find-symbol "T3")
NIL
NIL
T1> (defpackage t2)
#<Package "T2">
T1> (defpackage #:t3)
#<Package "T3">
T1> (find-symbol "T2")
T2
:INTERNAL
T1> (find-symbol "T3")
NIL
NIL
Как видите, использование t2
впервая форма defpackage
помещает ее в пакет t1
, а использование #:t3
во второй defpackage
позволяет избежать этого.Это возможно, потому что defpackage
принимает строковый указатель в качестве первого элемента, и символ не должен быть интернирован, чтобы функционировать в качестве указателя.
Эти и связанные ситуациигде неинтернизированные символы в основном используются намеренно.Вы также можете избежать загрязнения пакета, используя строку или ключевое слово, но в первом случае могут возникнуть проблемы с людьми, использующими не считываемый случай по умолчанию, а во втором случае вы будете загрязнятьпакет ключевых слов, который волнует некоторых людей.(Существуют разные мнения относительно того, действительно ли это так плохо или нет.)
Затем возникают ситуации, когда символ теряет свой домашний пакет (например, unintern
ing) и становитсяпо крайней мере, , очевидно, без стажировки .(Он все еще может быть интернирован в другой пакет.)
T1> (defparameter *t2* (find-symbol "T2"))
*T2*
T1> (import *t2* "T3")
T
T1> (symbol-package *t2*)
#<Package "T1">
T1> (unintern *t2*)
T
T1> (find-symbol "T2")
NIL
NIL
T1> (symbol-package *t2*)
NIL
T1> *t2*
#:T2
T1> (find-symbol "T2" "T3")
#:T2
:INTERNAL
T1> (unintern *t2* "T3")
T
T1> (import *t2* "T3")
T
T1> *t2*
T3::T2
T1> (symbol-package *t2*)
#<Package "T3">
Итак, ответ на
Есть ли способ интернировать символ, созданный с помощью (make-symbol)?
- это да:
T1> (import (make-symbol "T4"))
T
T1> (find-symbol "T4")
T4
:INTERNAL
Могу ли я присвоить значение символу без его интернирования?
Да, пока вытеряя свойство, которое может быть однозначно идентифицировано его именем и пакетом, вы все равно можете использовать его слот значения, plist и т. д.:
T1> (let ((symbol '#:t5))
(setf (symbol-value symbol) 1)
(setf (get symbol :foo) :bar)
(setf (symbol-function symbol) (lambda ()))
(values (symbol-value symbol)
(get symbol :foo)
(symbol-function symbol)))
1
:BAR
#<Anonymous Function #xC829036>
Можно ли переименовать символ (интернированныйили нет)?
Последствия изменения имени символа не определены.
Что еще можно сделать с неинтернизированным символом?
Я действительно думаю, что они в основном используются в качестве обозначений в определениях пакетов, но общий ответ будет таким: они могут быть полезны в ситуациях, когда вы хотите назвать вещи без использования жестко закодированных строк и не хотите загрязнять какой-либо пакет.