使用defvar时* var *和var之间有什么区别?

时间:2012-08-13 10:53:15

标签: lisp common-lisp

在某些文档中,我发现他们说答案是*var*意味着全局变量。

但是当我尝试时,我无法确定。

  FIRST-PACKAGE[27]> (defvar b 1)
  B
  FIRST-PACKAGE[28]> b
  1
  FIRST-PACKAGE[29]> (defun add_b (x) (+ x b))
  ADD_B
  FIRST-PACKAGE[30]> (add_b 3)
  4
  FIRST-PACKAGE[31]>

在我的示例中,如果答案是正确的,b仍然不是全局的。

但是为什么函数add_b仍然可以使用它?

如何理解此示例和*var*

谢谢〜

3 个答案:

答案 0 :(得分:1)

我在这里谈论Common Lisp:

DEFVAR声明一个全局变量并声明它使用动态绑定。它是特殊变量。我们使用*b*及其周围的星号作为约定来提醒我们它是特殊变量 - 它使用动态绑定。任何其他名称都可以。这只是一个惯例。在您的示例中,您使用名称b。我不建议这样做。请遵循惯例,并将DEFVAR声明的变量命名为*b*。同样的规则对DEFPARAMETER非常有用。

您对自己的例子的意思尚不清楚。当然,您可以在函数内部使用全局变量。

答案 1 :(得分:0)

好的。在Common Lisp中,实际上有两种类型的变量:一直使用的变量,它们是词法绑定的,而“特殊”变量是动态绑定的。使用defvardefparameter或声明创建“特殊”变量。 *earmuffs*是一种约定,用于提醒Lisp程序员变量是特殊的。以下是一些例子:

(defvar b 3)

(defun add-to-b (x)
  (+ x b))

(add-to-b 1)
  => 4

(let ((b 4))
  (list (add-to-b 1) b))
=> (5 4)

(let ((a 3))
  (defun add-to-a (x)
    (+ x a)))

(add-to-a 1)
  => 4

(let ((a 4))
  (list (add-to-a 1) a))
=> (4 4)

正如您所看到的,更改let中特殊变量的值会使值“逐渐减少”到let中的所有函数调用,而常规值会发生变化,词法绑定变量不会传递下去,实际上,通过向上移动位于函数wan 定义的范围内来查找词法绑定变量,同时通过移动查找特殊变量向上调用函数的范围*earmuffs*对于阻止程序员意外重新绑定特殊变量很有用,因为它们使特殊变量看起来不同。

答案 2 :(得分:-1)

首先:为了在Common Lisp中声明一个“特殊”变量,你必须通过defvar引入它:

(devar *variable* "initial value")

变量名称周围的“耳罩”(*)仅仅是一种约定,告诉人类读者,该变量是特殊的。这与告诉编译器变量是特殊的无关。请注意,*字符是变量名称的一部分(是的,Common Lisp允许符号名称中的* - 以及一大堆其他“异常”字符)