## **LISP 中的变量是什么?**
在 LISP 中,**变量**由**符号(symbol)** 表示。变量的名称就是符号的名称,而符号存储单元中保存着它的值。不同于许多编程语言,LISP 中的变量不需要声明类型,变量的类型是由其赋值决定的。
**速记句:** 变量就是符号,符号中存储着值。
全局变量
全局变量是指在整个 LISP 系统中都可以访问的变量,其值在被重新赋值之前始终有效。全局变量通常通过 defvar
构造来定义。例如:
(defvar x 234)
(write x) ; 输出:234
在这个例子中,x
是一个全局变量,初始值为 234。全局变量可以通过符号引用,甚至可以在任何地方访问。
速记句: 全局变量在整个程序中都可以访问。
使用 setq 赋值变量
在 LISP 中,你可以使用 setq
来为变量赋值。它的语法非常简单,例如:
(setq x 10)
这条语句将值 10
赋给变量 x
。重要的是,LISP 中的变量是无类型的,因此你可以自由地给变量赋值任何类型的数据。
速记句: setq
是给变量赋值的工具。
提取变量值:symbol-value
LISP 中的 symbol-value
函数允许你提取存储在符号中的值。例如,假设已经定义了变量 x
,你可以通过以下方式获取其值:
(setq x 10)
(symbol-value 'x) ; 返回:10
symbol-value
直接返回符号的当前值。
速记句: 用 symbol-value
获取符号的值。
局部变量
局部变量是在特定的函数或代码块中定义的,它们的作用范围仅限于该函数或代码块。例如,函数的参数就是局部变量。局部变量也可以使用 setq
来赋值。除此之外,LISP 提供了 let
和 prog
这两种构造来创建局部变量。
速记句: 局部变量只在它们的作用范围内有效。
使用 let 创建局部变量
LISP 中的 let
构造可以用来定义局部变量。它的语法如下:
(let ((var1 val1) (var2 val2) ...) <s-expressions>)
例如:
(let ((x 'a) (y 'b) (z 'c))
(format t "x = ~a y = ~a z = ~a" x y z))
; 输出:x = A y = B z = C
在 let
结构中,变量 x
、y
和 z
被赋予了初始值,并且它们的作用范围仅限于 let
块内。
速记句: 用 let
定义临时变量,范围仅在 let
内。
prog 构造与局部变量
prog
是另一种定义局部变量的构造。它的第一个参数是局部变量列表,后面跟着一系列要执行的 S 表达式。prog
按顺序执行这些表达式,直到遇到 return
,这时将返回 return
的值。
例如:
(prog ((x '(a b c)) (y '(1 2 3)) (z '(p q 10)))
(format t "x = ~a y = ~a z = ~a" x y z))
; 输出:x = (A B C) y = (1 2 3) z = (P Q 10)
速记句: prog
顺序执行表达式,局部变量仅在 prog
内有效。
变量的动态绑定
在 LISP 中,变量的绑定方式通常是动态的。也就是说,变量的值在不同的函数调用中可能会发生变化。例如,当在一个函数内重新定义一个变量时,它的值会在该函数内部有效。
(let ((x 5))
(format t "x 在函数内 = ~a" x))
(format t "x 在函数外 = ~a" x) ; 假设外部有定义
速记句: 动态绑定让变量在函数调用时可变。
变量未赋值时的默认值
如果你在 let
结构中没有为某个变量赋初值,那么该变量的默认值将是 nil
。例如:
(let ((x 10) (y))
(format t "x = ~a y = ~a" x y)) ; 输出:x = 10 y = NIL
速记句: 没有初值的变量默认值为 nil
。
总结
在 LISP 中,变量的定义和使用十分灵活。全局变量通过 defvar
定义,局部变量通过 let
和 prog
构造来创建。LISP 中变量的绑定是动态的,未赋值的变量默认为 nil
。通过 setq
可以为变量赋值,使用 symbol-value
可以获取变量的当前值。
参考文献:
- LISP 菜鸟教程 - LISP 变量
欢迎来到这里!
我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。
注册 关于