我有一个类,希望在创建对象时将某些槽位设置为 nil,但这些槽位只能由特定类型的对象设置。例如:
(defclass Something ()
((foo :initarg :foo
:type (or character 'nil)
:initform nil
:accessor something-foo)))
如果我说只是:type character
,或:type (or character nil)
,那么 SBCL 会抱怨它NIL
不属于断言的字符类型。如果我说:type (or character 'nil)
,那么它似乎接受字符和符号类型,因为任何符号似乎都适用:
CL-USER> (defvar *foo* (make-instance 'Something))
*FOO*
CL-USER> (setf (something-foo *foo*) 'test)
TEST
CL-USER> (something-foo *foo*)
TEST
有没有办法断言一个 slot 是 nil 还是具有给定的类型?或者我应该省略类型说明符,然后在访问器或写入器方法中断言类型?
编辑:
再三考虑之后,也许习惯用法是说:type character
但保持其不受约束,然后检查插槽是否被绑定,而不是检查是否为零和非零?
NIL
是空类型,它根本不包含任何值(就像数学中的空集)。包含该值的类型
NIL
是NULL
。所以你想要的是请记住:复合类型中的类型不会被评估,因此您不需要也不能引用它们。
该对象属于什么类型
NIL
?那么,
nil
是 类型吗null
?那么,
nil
是 类型吗(or character null)
?null
我们也可以使用类型来代替(eql nil)
。此类型描述的是 对象的集合nil
。我们可以在类型表达式中使用它:我们还可以
member
在类型表达式中使用类型,其中nil
的类型为(member nil)
:因此,复合类型
(member nil)
和(eql nil)
描述的对象与标准化原子类型说明符null
相同。它们中的任何一个都可以在你的插槽类型中使用,但我更喜欢使用最简单的类型,即这里的 类型NULL
。