变量

局部变量

局部变量与任何其他语言中的行为相同:它们是正常词法作用域的变量。

变量使用 let 特殊运算符声明

(let ((str "Hello, world!"))
  (string-upcase str))

;; => "HELLO, WORLD!"

您可以定义多个变量

(let ((x 1)
      (y 5))
  (+ x y))

;; => 6

若要定义初始值依赖于同一表单中前面变量的变量,请使用 let*

(let* ((x 1)
       (y (+ x 1)))
  y)

;; => 2

动态变量

动态变量类似于全局变量,但更有用:它们是动态作用域的。您可以使用 defvardefparameter 定义它们,不同之处在于

  1. defparameter 需要一个初始值,defvar 不需要。
  2. 在重新加载代码时使用新初始值就会更改 defparameter 变量,defvar 变量则不会。

动态作用域是什么意思?这意味着

(defparameter *string* "I'm global")

(defun print-variable ()
  (print *string*))

(print-variable) ;; Prints "I'm global"

(let ((*string* "I have dynamic extent")) ;; Binds *string* to a new value
  (print-variable)) ;; Prints "I have dynamic extent"
;; The old value is restored

(print-variable) ;; Prints "I'm global"

换句话说,当您使用 let 重新定义动态变量的值时,该变量绑定到 let 主体内的该新值,并且随后“恢复”旧值。