sam*_*sam 41 lisp clisp common-lisp
我发现了一个类似的问题.
但我不太明白这个解释.
所以我试图使用以下示例运行clisp:
[1]> (defvar a 5)
A
[2]> (+ a 1)
6
[3]> (defparameter b 5)
B
[4]> (+ b 1)
6
[5]> (setf c 5)
5
[6]> (+ c 1)
6
[7]> (setq d 5)
5
[8]> (+ d 1)
6
[9]> (let ((a 500)) (+ a 1))
501
[10]> (let ((b 500)) (+ b 1))
501
[11]> (let ((c 500)) (+ c 1))
501
[12]> (let ((d 500)) (+ d 1))
501
[13]>
Run Code Online (Sandbox Code Playgroud)
我发现的完全一样.
我无法弄清楚它们有什么不同?
Mic*_*ski 65
DEFPARAMETER总是赋值.所以:
[1]> (defparameter a 1)
A
[2]> (defparameter a 2)
A
[3]> a
2
Run Code Online (Sandbox Code Playgroud)
而DEFVAR只做一次,所以:
[4]> (defvar b 1)
B
[5]> (defvar b 2)
B
[6]> b
1
Run Code Online (Sandbox Code Playgroud)
SETF是一个内部使用SETQ的宏,但有更多的可能性.在某种程度上,它是一个更通用的赋值运算符.例如,使用SETF,您可以:
[19]> (defparameter c (list 1 2 3))
[21]> (setf (car c) 42)
42
[22]> c
(42 2 3)
Run Code Online (Sandbox Code Playgroud)
但你不能用SETQ做到这一点:
[23]> (setq (car c) 42)
*** - SETQ: (CAR C) is not a symbol
The following restarts are available:
USE-VALUE :R1 Input a value to be used instead.
ABORT :R2 Abort main loop
Break 1 [24]> abort
Run Code Online (Sandbox Code Playgroud)
Vat*_*ine 25
双方defvar并defparameter会声明一个变量为"动态范围变量".此外,defparameter将始终将变量的值设置为您传入的值作为第二个参数.这defvar与之不同,它只会设置变量的值(如果之前尚未设置).
使用setf或setq在全局词法范围内定义变量是未定义的.一些实现将为您创建动态范围的变量,有些则不会.第一次执行此操作时,您可能会看到诊断消息.
要了解词法范围变量和动态范围变量之间的区别,请尝试以下代码段:
* (defvar *a* 1)
*A*
* (let ((*a* 5)) (defun demo-a () *a*))
DEMO-A
* (let ((b 5)) (defun demo-b () b))
DEMO-B
* (let ((*a* 100)) (demo-a))
100
* (let ((b 100)) (demo-b))
5
Run Code Online (Sandbox Code Playgroud)
在这里,我们创建一个动态范围的变量和一个返回值的函数(在一个绑定中定义,它在函数创建过程中具有不同的值,这不是必需的,只是看起来类似于b上的词法闭包).然后我们定义一个新变量并定义一个函数返回它的值.
之后,我们调用两个函数,在闭包内将值绑定到同名变量.在动态范围的情况下,它是相同的变量.在词汇闭包案例(b)中,它们只是具有相同的名称,但不是相同的变量,因为它们是在两个不同的词汇闭包中定义的.
至于setf和之间的区别setq,尽量使用setf(我想不出任何(setq blah blahblah)可行的例子,(setf blah blahblah)也不会做同样的事情).
| 归档时间: |
|
| 查看次数: |
17373 次 |
| 最近记录: |