2.11 赋值 (Assignment)

在 Common Lisp 里,最普遍的赋值操作符(assignment operator)是 setf 。可以用来给全局或局部变量赋值:

  1. > (setf *glob* 98)
  2. 98
  3. > (let ((n 10))
  4. (setf n 2)
  5. n)
  6. 2

如果 setf 的第一个实参是符号(symbol),且符号不是某个局部变量的名字,则 setf 把这个符号设为全局变量:

  1. > (setf x (list 'a 'b 'c))
  2. (A B C)

也就是说,通过赋值,你可以隐式地创建全局变量。 不过,一般来说,还是使用 defparameter 明确地创建全局变量比较好。

你不仅可以给变量赋值。传入 setf 的第一个实参,还可以是表达式或变量名。在这种情况下,第二个实参的值被插入至第一个实参所引用的位置:

  1. > (setf (car x) 'n)
  2. N
  3. > x
  4. (N B C)

setf 的第一个实参几乎可以是任何引用到特定位置的表达式。所有这样的操作符在附录 D 中被标注为 “可设置的”(“settable”)。你可以给 setf 传入(偶数)个实参。一个这样的表达式

  1. (setf a 'b
  2. c 'd
  3. e 'f)

等同于依序调用三个单独的 setf 函数:

  1. (setf a 'b)
  2. (setf c 'd)
  3. (setf e 'f)