【问题标题】:What is the exact difference between NULL and NIL in Common Lisp?Common Lisp 中 NULL 和 NIL 的确切区别是什么?
【发布时间】:2014-07-12 15:09:07
【问题描述】:

据我了解,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" 也不是一个。但是我对 NULL 这个术语有点困惑,因为无论是否被否定,布尔值都应该保持为布尔值。

【问题讨论】:

  • 试试(type-of "elephant")(type-of (not "elephant"))t 恰好是布尔值这一事实是偶然的。

标签: lisp common-lisp null


【解决方案1】:

NIL 是一个符号。它也写成()type-of 的输出在这里不一定有用。 HyperSpec 提到了type-of

返回一个类型说明符,typespec,用于具有对象的类型 一个元素。

但是给定类型层次结构以及通用类型(所有类型都是t),type-of 的输出可能没有帮助。如果您想知道某物是否具有特定类型,这里更有用的是typep。使用 typep,我们可以看到,不管 type-of 告诉我们什么,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

【讨论】:

    【解决方案2】:

    您可能会认为 T 是布尔值而 NIL 不是布尔值很奇怪。原因是NIL 有几顶帽子。这是一个空列表,它是符号 NIL,它是布尔值 false。所以它有时出现在不适合布尔类型值的上下文中,因此从类型安全的角度来看,布尔类型不适合它。有点类似,在 Scheme 中 boolean false 与空列表不同。

    NULL 作为typeNIL 给出。

    NIL 是 Common Lisp 中表示 NULL 的符号。它也是空列表()的表示。 #'NULL 是检查变量是否为 NULL 的函数(即。eqNIL)。

    如果您想使用 NULL 而不是 NIL,您可以定义 NULL。 (这在实践中可能是一个糟糕的想法。

    (defconstant null nil)
    (type-of NULL) ; ==> NULL
    NULL           ; ==> NIL
    (eq NULL NIL)  ; ==> T
    

    【讨论】:

    • 最能帮助我理解的是,NIL 实际上只是一个符号,但却是一个非常特殊的符号。
    • 虽然可以定义 null,但这可能不是一个好主意,因为它会导致单调的代码让人措手不及。
    • “你可能会觉得奇怪的是 T 是布尔值,而 NIL 不是。” 除了 nil 是布尔值,如 @987654335 @确认。
    • @JoshuaTaylor CL 中的每个对象都是一个布尔值。当我写这篇文章时,我写了 OP 在使用 type-of 时所经历的事情。因此最具体的类型。另请注意,@osa 在我一年多前编写后对其进行了编辑。
    • 是和否...我明白你的意思,但是为了找到这个问题的经验不足的读者,type boolean 只包含符号 t和零。但是 everythinggeneralized boolean,并且大多数运算符都接受广义布尔值。
    【解决方案3】:

    确切的区别在于 NULL 是您上下文中的一种类型,而 NIL 是一个符号。

    NULL 是只包含符号 NIL 的类型。

    NIL 作为类型是空类型(不存在 NIL 类型的对象):

    NIL 作为一个对象是代表各种“非”事物的符号。

    【讨论】:

      【解决方案4】:

      所以 NULL 不是一个已定义的符号,因为“BASIC-STRING-6”也不是一个。

      NULL 一个符号。它没有价值。符号NULL 是类型NULL 和函数NULL 的名称。 NULL 作为一种类型有一个元素:NIL

      NIL 是一个符号,NIL 是它的值。因此NIL 是一个以自身为值的常量。 NIL 也是一个类型,没有对象的空类型。

      【讨论】:

        【解决方案5】:

        INTEGER、(ARRAY *)、(MEMBER T NIL) 等类型指示符不会计算为值。因此,如果您尝试评估类型名称 NULL 会引发错误,这并不奇怪。回想一下类型/子类型层次结构不是一棵简单的树,因此 NULL 是许多事物的子类型;缺点、布尔值、列表等

        请注意,许多不属于 BOOLEAN 类型的事物都被视为 true。 BOOLEAN 只是 '(member nil t) 的简写。所以 (type 'foo '(member nil t)) 等价于 '(typep 'foo 'boolean)。

        在学习曲线的这一点上值得记住的是,Common Lisp 是动态类型的,类型声明更倾向于文档化,并建议编译器的优化器和警告子系统可以采用或忽略哪些。

        NULL 也是一个函数。检查手册的索引可能对您有所帮助。

        【讨论】:

          猜你喜欢
          • 2015-07-03
          • 2016-02-18
          • 2015-07-05
          • 2012-01-16
          • 1970-01-01
          • 1970-01-01
          • 2012-03-25
          • 2011-04-20
          • 2010-10-07
          相关资源
          最近更新 更多