为什么当我创建一个 class 时找不到符号呢?
Why when I create an class can't find-symbol it?
我现在对符号感到困惑,我试过了:
CL-USER> (defclass foo2 () ())
#<STANDARD-CLASS COMMON-LISP-USER::FOO2>
CL-USER> (describe 'foo2)
COMMON-LISP-USER::FOO2
[symbol]
FOO2 names the standard-class #<STANDARD-CLASS COMMON-LISP-USER::FOO2>:
Direct superclasses: STANDARD-OBJECT
No subclasses.
Not yet finalized.
No direct slots.
; No value
CL-USER> (find-symbol "foo2")
NIL
NIL
为什么我用 find-symbol
函数找不到 "foo2" 符号?
我想用这个做什么:
CL-USER> (defun my-make-instance (name n) (make-instance (make-symbol (format nil "~a-~a" name n)))
MY-MAKE-INSTANCE
CL-USER> (my-make-instance "foo" 2)
; Evaluation aborted on #<SB-PCL:CLASS-NOT-FOUND-ERROR foo2 {1003A3A003}>.
然后我得到:
There is no class named #:|foo2|.
我该怎么做?
其他情况:
CL-USER> (describe 'foo2)
COMMON-LISP-USER::FOO2
[symbol]
FOO2 names the standard-class #<STANDARD-CLASS COMMON-LISP-USER::FOO2>:
Direct superclasses: STANDARD-OBJECT
No subclasses.
Not yet finalized.
No direct slots.
; No value
CL-USER> (describe (intern "foo2"))
COMMON-LISP-USER::|foo2|
[symbol]
; No value
为什么会这样? defclass 创建的 "foo2" 是内部符号吗?
- Common Lisp 区分大小写,reader 是大小写转换;当编译器/解释器读取源代码时,它通常会转换为大写。名为 "foo2" 的符号在您的示例中不存在,但名为 "FOO2" 的符号存在。
- 对
make-symbol
的调用将 return 一个新的符号对象,而不是与您的 class 关联的符号对象。
修复代码的最简单方法是将 my-make-instance
中的 make-symbol
调用替换为对 read-from-string
的调用,以获得相同的大小写转换 reader 行为用于您的参数字符串。然后 reader 还将在当前包中实习该符号,确保它与与您的 class 关联的符号对象相同。在这种情况下,您可能还想使用 defun
而不是 defmacro
来定义 my-make-instance
。
简而言之,您可能需要以下代码:
(defun my-make-instance (name n)
(make-instance (read-from-string (format nil "~a-~a" name n))))
(defclass foo-2 () ())
(my-make-instance "foo" 2)
;returns below instance
#<FOO-2 {100AB67443}>
如果你描述符号并得到
FOO2
names the standard-class #<STANDARD-CLASS COMMON-LISP-USER::FOO2>
:
然后 FOO2
in uppercase characters 确实表明该符号具有大写名称。
* 'foo2
FOO2
现在您可以使用函数 symbol-name
将交易品种的名称作为字符串获取:
* (symbol-name 'foo2)
"FOO2"
正如你在上面看到的,名字是大写的。
然后使用大写名称查找符号有效:
* (find-symbol "FOO2")
FOO2
:INTERNAL
我现在对符号感到困惑,我试过了:
CL-USER> (defclass foo2 () ())
#<STANDARD-CLASS COMMON-LISP-USER::FOO2>
CL-USER> (describe 'foo2)
COMMON-LISP-USER::FOO2
[symbol]
FOO2 names the standard-class #<STANDARD-CLASS COMMON-LISP-USER::FOO2>:
Direct superclasses: STANDARD-OBJECT
No subclasses.
Not yet finalized.
No direct slots.
; No value
CL-USER> (find-symbol "foo2")
NIL
NIL
为什么我用 find-symbol
函数找不到 "foo2" 符号?
我想用这个做什么:
CL-USER> (defun my-make-instance (name n) (make-instance (make-symbol (format nil "~a-~a" name n)))
MY-MAKE-INSTANCE
CL-USER> (my-make-instance "foo" 2)
; Evaluation aborted on #<SB-PCL:CLASS-NOT-FOUND-ERROR foo2 {1003A3A003}>.
然后我得到:
There is no class named #:|foo2|.
我该怎么做?
其他情况:
CL-USER> (describe 'foo2)
COMMON-LISP-USER::FOO2
[symbol]
FOO2 names the standard-class #<STANDARD-CLASS COMMON-LISP-USER::FOO2>:
Direct superclasses: STANDARD-OBJECT
No subclasses.
Not yet finalized.
No direct slots.
; No value
CL-USER> (describe (intern "foo2"))
COMMON-LISP-USER::|foo2|
[symbol]
; No value
为什么会这样? defclass 创建的 "foo2" 是内部符号吗?
- Common Lisp 区分大小写,reader 是大小写转换;当编译器/解释器读取源代码时,它通常会转换为大写。名为 "foo2" 的符号在您的示例中不存在,但名为 "FOO2" 的符号存在。
- 对
make-symbol
的调用将 return 一个新的符号对象,而不是与您的 class 关联的符号对象。
修复代码的最简单方法是将 my-make-instance
中的 make-symbol
调用替换为对 read-from-string
的调用,以获得相同的大小写转换 reader 行为用于您的参数字符串。然后 reader 还将在当前包中实习该符号,确保它与与您的 class 关联的符号对象相同。在这种情况下,您可能还想使用 defun
而不是 defmacro
来定义 my-make-instance
。
简而言之,您可能需要以下代码:
(defun my-make-instance (name n)
(make-instance (read-from-string (format nil "~a-~a" name n))))
(defclass foo-2 () ())
(my-make-instance "foo" 2)
;returns below instance
#<FOO-2 {100AB67443}>
如果你描述符号并得到
FOO2
names the standard-class#<STANDARD-CLASS COMMON-LISP-USER::FOO2>
:
然后 FOO2
in uppercase characters 确实表明该符号具有大写名称。
* 'foo2
FOO2
现在您可以使用函数 symbol-name
将交易品种的名称作为字符串获取:
* (symbol-name 'foo2)
"FOO2"
正如你在上面看到的,名字是大写的。
然后使用大写名称查找符号有效:
* (find-symbol "FOO2")
FOO2
:INTERNAL