elisp 里的变量使用无需像 C 语言那样需要声明。
C-h v
查看变量的文档。
1 | (set 'foo "I'm foo") ; => "I'm foo" |
set 命令需要在变量前加上引用。setq 是对 set 的简化。使用它无需在变量前加上引用。
1 | (setq foo "I'm foo") ; => "I'm foo" |
defvar
可以声明一个变量。形式:
1 | (defvar variable-name value |
它与 setq 不同之处在于:如果变量在声明之前,这个变量已经有一个值的话,用 defvar 声明的变量值不会改变成声明的那个值。另一个区别是 defvar 可以为变量提供文档字符串,当变量是在文件中定义的话,C-h v
后能够给出变量定义的位置。比如:
1 | (defvar foo "Did I have a value?" |
可以用 let 和 let* 进行局部变量的绑定。let 使用的形式是:
1 | (let (bindings) |
bindings
可以是 (var value)
这样对 var 赋初始值的形式。也可以只用 var
声明一个初始值为 nil 的变量。比如:
1 | (defun circle-area (radix) |
C-h v
查看 area
和 pi
应该没有这两个变量。
let 和 let* 的使用形式完全相同,唯一的区别是在 let* 声明中就能使用前面声明的变量,比如:
1 | (defun circle-area (radix) |
形式:
1 | (defun function-name (argument-list) |
示例:
1 | (defun hello (name) |
形式:
1 | (hello "Emacser") ; => "Hello, Emacser" |
每个函数都有一个返回值。这个返回值一般是函数定义里的最后一个表达式的值。
C-h f
查看函数的文档。
形式:
1 | (lambda (arguments-list) |
调用方法:
1 | (funcall (lambda (name) |
你也可以把 lambda 表达式赋值给一个变量,然后用 funcall 调用:
1 | (setq foo (lambda (name) |
lambda 表达式最常用的是作为参数传递给其它函数。
条件的逻辑运算和其他语言都是很类似的,使用 and、or、not。and 和 or 也同样具有短路性质。很多人喜欢在表达式短时,用 and 代替 when,or 代替 unless。当然这时一般不关心它们的返回值,而是在于表达式其它子句的副作用。比如 or 经常用于设置函数的缺省值,而 and 常用于参数检查:
1 | (defun hello-world (&optional name) |
1 | (defun NAME ARGLIST [DOCSTRING] BODY...) |