功能
这两个函数其实是一个,只是逻辑上用在不同的场合。
setq用于给symbol的reference设置,而setf用于设置list 或者 array的reference.
setq的使用
setq比较简单,避免了在使用set的时候用‘来阻止表达式求值。
> (setq x "hello")
"hello"
> x
"hello"
setf的使用
> (setq L '(a b (c d) e f g))
(a b (c d) e f g)
> L
(a b (c d) e f g)
> (setf (L 1) 'B)
B
> L
(a B (c d) e f g)
> (L 1)
B
>
setf用于设置list或者array的reference,上面的例子首先用setq设置了L, 其值是一个list
然后用setf 将B symbol赋给了L的第二个元素b
因为B是一个symbol,我们可以对它赋值,看下面的代码:
> (setq B "He")
"He"
> (L 1)
B
> (eval (L 1))
"He"
>
用eval将B的值取出来。
setf的复杂应用
下面这个例子来自官方文档:
(define (double x) (+ x x))
→ (lambda (x) (+ x x))
(first double) → (x)
(last double) → (+ x x)
; make a fuzzy double
(setf (nth 1 double) '(mul (normal x (div x 10)) 2))
(double 10) → 20.31445313
(double 10) → 19.60351563
首先定义了一个lambda表达式。
然后用setf把lambda表达式的body,也就是第二个元素设置成了list (mul (normal x (div x 10)) 2)
这个list用来计算随机数,并和2相乘。
这个例子演示了再define之后也可以通过setf来修改lambda表达式。