‘set’、‘setq’和‘setf’在共同的Lisp中的区别?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (15)

在通用Lisp中,“set”、“setq”和“SETF”有什么区别?

提问于
用户回答回答于

最初,在Lisp中,没有词汇变量 - 只有动态变量。并没有SETQ或SETF,只有SET功能。

现在写为:

(setf (symbol-value '*foo*) 42)

被写为:

(set (quote *foo*) 42)

最终被缩写为SETQ(SET引用):

(setq *foo* 42)

然后发生了词汇变量,并且SETQ也被用于赋值给它们 - 所以它不再是SET的简单包装。

后来,有人发明了SETF(SET Field)作为为数据结构赋值的通用方法,以反映其他语言的l值:

x.car := 42;

会写成

(setf (car x) 42)

为了对称和一般性,SETF还提供了SETQ的功能。在这一点上,说SETQ是一个低级原语,而SETF是一个高级操作,这是对的。

然后符号宏发生。因此,符号宏可以透明地工作,它意识到如果被赋予的“变量”实际上是符号宏,那么SETQ将必须像SETF一样行事:

(defvar *hidden* (cons 42 42))
(define-symbol-macro foo (car *hidden*))

foo => 42

(setq foo 13)

foo => 13

*hidden* => (13 . 42)
用户回答回答于
(set ls '(1 2 3 4)) => Error - ls has no value

(set 'ls '(1 2 3 4)) => OK

(setq ls '(1 2 3 4)) => OK - make ls to (quote ls) and then have the usual set

(setf ls '(1 2 3 4)) => OK - same as setq so far BUT

(setf (car ls) 10) => Makes ls '(10 2 3 4) - not duplicated by setq/set

扫码关注云+社区