我只是把自己原来不清楚的点记录下来,方便自己查阅,同时希望点醒其他人。
defvar 可以对变量添加document string(文档说明)
defvar 只用做初始化变量,如果变量之前有值,则不会再进行赋值
(defvar variable-name value
"document string")
setq 不用像set一样在变量名前加’(单引号)
setq 不仅可以初始化变量,还可以进行变量赋值操作
(setq foo "I'm foo"); => "I'm foo"
let* 和 let 的使用形式完全相同,唯一的区别是在 let* 声明中就能使用前面声明的变量,比如:
(defun circle-area (radix)
(let* ((pi 3.1415926)
(area (* pi radix radix)));这里给area赋值用了前面声明的变量pi的值
(message "直径为 %.2f 的圆面积是 %.2f" radix area)))
let 和 let* 操作的都是局部变量,let块内的局部变量,所以都是在进行初始化操作,之后BODY内执行命令优先处理局部变量
如果我无法说明白,请看下面的演示
(progn
(setq pi 3.14231241412);全局变量pi=3.14231241412
(let ((pi 3.1415926);外层let块的局部变量pi=3.1415926
)
(setq pi 3);pi(外)被赋值为3
(message "pi: %.9f" pi);输出结果:3.000000000
(let ((pi 3.2));内部let块声明局部变量pi=3.2
(message "%.9f" pi));输出结果为:3.200000000
(message "%.9f" pi)));处于外层let BODY,输出结果为:3.000000000
(message "pi: %.9f" pi);输出结果为:3.14231241412
是一个函数,只能带一个执行体,如果要执行多个命令,需要用progn连接他们
是一个宏(macro)能够执行多个命令,并且不用progn连接他们
这是他的展开
(macroexp--expand-all '(when (= n 1)
(message "hello")
(message "world")
))
;(if (= n 1) (progn (message "hello") (message "world")))
是一个宏,看他的展开就会一目了然
(macroexp--expand-all '(unless (= n 1) (message "111") (message "111")))
;(if (= n 1) nil (message "111") (message "111"))
这样就不用加progn也能够实现多条语句执行,因为满足条件执行nil,否则执行其他的所有。
Elisp中函数的返回值一般是最后一个表达式的返回值,符号前面如果不加单引号,则会进行求值,所以可以将符号直接放在函数最后当作返回值。如果加上单引号,则是返回符号或者表达式本身。
一个函数后面带p比如,region-active-p,他们一般是用作判断,返回值只有t和nil。
有 and or not,他们的返回值不都是是 t 或者 nil 有的是一个值。具体看下面:
当所有条件都是non-nil时才为真,但是他返回的可不是t,而是最后一个non-nil值
而如果条件中有一个nil,那么他就立刻返回nil,后面的表达式都不会执行,这是叫做短路。
(and 1 2 3 4 5);返回5
(and nil (progn
(setq n 10)
(message "n=%d" n)));不会执行后面语句,直接返回nil
当所有条件都为nil时才返回nil,否则返回他所碰到的第一个non-nil的值
(or nil nil nil nil);返回nil
(or nil nil (progn
(message "我被执行了")));执行message命令
不具有短路性质,只会返回t 和 nil
= 不是赋值操作符 而是比较操作符
set才被用来进行赋值
并且 = 对于浮点数的相等测试是不可靠的,浮点数是不精确的
(eql)测试数字是否想等,不仅测试数字的值是否想等,还测试数字的类型是否一致
如:
(= 1.0 1);t
(eql 1.o 1);nil 因为浮点数不是整数
/= 是不等于的判断测试
并没有+= -= *=这类操作,只能通过set/setq来实现
(float)能把整数转化成浮点数
浮点数转化成整数: