本帖最后由 baitang36 于 2024-7-4 09:14 编辑
先看一下桌子关于and这个函数的说明:
And
Returns the logical AND of the supplied arguments ;返回所提供参数的逻辑AND (and [expr ...])
Arguments;参数
expr ;表达式Any expression.
Return Values
Nil, if any of the expressions evaluate to nil; otherwise T. If and is issued without arguments, it returns T.
返回值:
如果任何一个表达式的求值结果为Nil,就返回nil;否则返回T。
如果在没有参数的情况下则返回T。
通过跟踪fas内存中的and指令,发现桌子这个说明是不完全的。
完整的应该这样说:and指令是对表达式按顺序进行求值(运行),如果结果是T,会继续对下一个表达式求值,如果结果是nil,结束and指令,返回nil,后面的表达式被跳过,不会被求值。如果最后一个表达式求值完成,结果是t,and指令返回T。
说的比较啰嗦,用代码来说明:
(and (setq a 1)(setq b 2)(setq c nil)(setq d 4)) 加载后返回nil ,但(setq d 4)这个表达式是被跳过了,nil 后面的表达式不会被求值。
在命令行验证一下:
命令: (setq d nil)
nil
命令: (and (setq a 1)(setq b 2)(setq c nil)(setq d 4))
nil
命令: !d
nil
根据上面的原理,我们可以用and来代替if
(if (= a 1)
(setq b 2)
)
可以用
(and (= a 1)(setq b 2))代替,b的结果是一样的
可以用两个and来替换(if testexpr thenexpr elseexpr)
(and testexpr thenexpr )
(and (not testexpr) elseexpr)
或者(or (and a b) c)
and表达式里面加progn,可以让反编译的结果混乱,不能运行。
(defun tt()
(and (setq a 1)
(progn(setq b 2)(setq c nil)(setq d 4))
)
)
;(vlisp-compile 'st "d:/and1.lsp")
编译后再反编译progn没了,d的结果就不对了
|