变量和常量

Table of Contents

1. 变量

defvar:定义一个符号,如果符号存在的话,不会修改符号。

defparameter:定义一个符号,如果符号存在,就变成新值,否则创建。

setf/setq:给变量赋值。setq 不能给复合结构赋值,如:

(defvar xlist '(x x x))
(setq (car xlist) 'y)                   ; Error

setq 过时了。

2. 绑定(Binding)

绑定的定义如下:

  • 符号和值建立了联系,称为“bound”,如:(defvar a 1)。类似其他编程语言中给变量复制的过程;
  • 符号没有值称为”unbound”,如:(defvar x);
  • 如果符号出现在函数参数列表中,称为“Lambda 绑定”;
  • 如果符号出现在 let 或 let* 形式中,叫“LET-binding”,或“本地绑定”。

2.1. 本地绑定

let:绑定一个本地变量。函数体最后个值作为表达式返回值。

(let ((x 1))
  (print x))

let*:和 let 区别在于,let* 绑定符号时,多个绑定的变量可以在 bindings 里互相调用:

(let* ((x 1) (y (1+ x)))
  (format t "~a ~a" x y))

再看这段代码:

(let* ((x 1) (y x))
  (print y))

如果改用 let 就会报错:The variable X is unbound.

2.2. 解构绑定

解构,就是按位置赋值,类似 Python 的:

a, b, c = [1, 2, 3]
print(a, b, c)                  # => 1 2 3

destructuring-bind 宏就用于解构绑定:

(destructuring-bind (a b c) '(1 2 3)
  (format t "~a ~a ~a" a b c))

3. 全局常量和变量

标准中规定了一些全局的变量和常量。

3.1. 常量

常量 用途
pi 具体的精度取决于 Common Lisp 实现。
most-negative-fixnum fixnum 类型允许的最小值。
most-positive-fixnum fixnum 类型允许的最大值。

3.2. 变量

3.3. *print-array*

如果值为 t,打印数组时会打印具体内容,否则只打印数组信息。

(setf *print-array* nil)                ; => NIL
(print #(1 2 3))
;; 输出:
;; #<(SIMPLE-VECTOR 3) {10031B641F}>
;; #<(SIMPLE-VECTOR 3) {10031B641F}>
(setf *print-array* t)                  ; => T
(print #(1 2 3))
;; 输出:
;; #(1 2 3)
;; #(1 2 3)