在公共Lisp中,NULL和NIL之间的确切区别是什么?
据我所知,NIL是许多事物的符号:空列表或布尔值false。到目前为止还不错,但是为什么有时候输出中会出现NULL呢在公共Lisp中,NULL和NIL之间的确切区别是什么?,lisp,common-lisp,null,Lisp,Common Lisp,Null,据我所知,NIL是许多事物的符号:空列表或布尔值false。到目前为止还不错,但是为什么有时候输出中会出现NULL呢 clisp> (type-of NIL) NULL clisp> (type-of t) BOOLEAN clisp> (type-of (not t)) NULL clisp> NIL NIL clisp> (eq NULL NIL) ERROR.. 所以NULL不是一个定义符号,因为“BASIC-STRING-6”也不是一个。但是我有点被术语N
clisp> (type-of NIL)
NULL
clisp> (type-of t)
BOOLEAN
clisp> (type-of (not t))
NULL
clisp> NIL
NIL
clisp> (eq NULL NIL)
ERROR..
所以NULL不是一个定义符号,因为
“BASIC-STRING-6”
也不是一个。但是我有点被术语NULL搞糊涂了,因为不管它是否被否定,布尔值应该仍然是布尔值。你可能会觉得奇怪,T
是布尔值,而NIL
不是。原因是NIL
有几个帽子。这是一个空列表,它是符号NIL,它是布尔值false。因此,它有时出现在不适合布尔类型值的上下文中,因此从类型安全的角度来看,布尔类型不适合它。类似地,在Scheme中boolean false与空列表不同
NULL作为NIL
的类型
NIL
是在公共Lisp中表示NULL的符号。它也是空列表的表示形式()
#'NULL
是检查变量是否为NULL的函数(即eq
NIL
)
如果要使用NULL而不是NIL,可以定义NULL。(实际上,这可能是一个糟糕的想法。)
确切的区别在于NULL是上下文中的一种类型,而NIL是一种符号
NULL是仅包含符号NIL的类型
类型为NIL的对象是空类型(没有类型为NIL的对象):
NIL作为一个对象是代表各种“非”事物的符号。NIL
是一个符号。它也写为()
。类型的输出在这里不一定有用。HyperSpec说:
返回对象为的类型的类型说明符typespec
元素
但给定类型层次结构以及通用类型(所有类型都是t
),类型的输出可能没有帮助。如果你想知道某物是否有特定的类型,这里更有用的是什么。使用typep,我们可以看到,无论什么类型的告诉我们,nil
是一个布尔值,是一个符号,是一个列表,是一个空值。另一方面,t是一个符号,一个布尔值,不是列表,也不是空值
CL-USER> (type-of nil)
NULL
CL-USER> (type-of t)
BOOLEAN
CL-USER> (typep nil 'boolean) ; both are booleans
T
CL-USER> (typep t 'boolean)
T
CL-USER> (typep nil 'symbol) ; both are symbols
T
CL-USER> (typep t 'symbol)
T
CL-USER> (typep nil 'list) ; only nil is a list
T
CL-USER> (typep t 'list)
NIL
CL-USER> (typep nil 'null) ; only nil is a null
T
CL-USER> (typep t 'null)
NIL
整数、(数组*)、(成员T NIL)等类型指示符的计算结果不是值。因此,如果您尝试对类型名称NULL求值,那么类型名称NULL会引发错误也就不足为奇了。回想一下,类型/子类型层次结构不是一个简单的树,因此NULL是许多事物的子类型;CONS、BOOLEAN、LIST等
请注意,许多不是布尔类型的事物被视为true。BOOLEAN只是“(成员nil t)的简写形式。所以(type'foo'(成员nilt))与(type'foo'boolean)相等
在学习曲线的这一点上,有必要记住公共Lisp是动态类型的,类型声明更倾向于文档化,并建议编译器的优化器和警告子系统可以接受或忽略哪些
NULL也是一个函数。检查手册的索引可能会对您有所帮助
所以NULL不是一个定义符号,因为“BASIC-STRING-6”也不是一个
NULL
是一个符号。它没有价值。符号NULL
是类型和函数的名称NULL
作为一个类型有一个元素:NIL
NIL
是一个符号,NIL
是它的值。因此,NIL
是一个常数,它本身就是一个值NIL
也是一种类型,一种没有对象的空类型。最有助于我理解的是,NIL实际上只是一个符号,但却是一个非常特殊的符号。虽然可以定义null
,但这可能不是一个好主意,因为它会导致单一的代码,让人措手不及。“你可能会认为T是布尔值而NIL不是很奇怪。”除了NIL是布尔值,如(typep NIL'布尔值)=>T
确认。@JoshuaTaylor CL中的每个对象都是布尔值。当我写这篇文章时,我写的是OP使用类型的
所经历的。因此是最具体的类型。还要注意@osa在我一年多前写了这篇文章后编辑了它。是和否……我理解你的意思,但为了那些发现这篇文章的经验较少的读者问题,该类型仅包含符号t和nil。但所有内容都是a,并且大多数运算符都接受广义布尔值。请尝试(大象的类型)
和(大象的类型)(不是大象的类型)
。t
恰好是布尔值的事实是偶然的。
CL-USER> (type-of nil)
NULL
CL-USER> (type-of t)
BOOLEAN
CL-USER> (typep nil 'boolean) ; both are booleans
T
CL-USER> (typep t 'boolean)
T
CL-USER> (typep nil 'symbol) ; both are symbols
T
CL-USER> (typep t 'symbol)
T
CL-USER> (typep nil 'list) ; only nil is a list
T
CL-USER> (typep t 'list)
NIL
CL-USER> (typep nil 'null) ; only nil is a null
T
CL-USER> (typep t 'null)
NIL