本帖最后由 highflybird 于 2019-8-1 00:13 编辑
首先我的个人观点觉得这个地方完全是Lee秀技巧有点过了,但实际并未达到他的目的。
1、分析他的这段代码:
 - (defun LM:acdoc nil
- (eval (list 'defun 'LM:acdoc
- 'nil
- (vla-get-activedocument (vlax-get-acad-object))
- )
- )
- (LM:acdoc)
- )
第一段 :  - (eval (list 'defun
- 'LM:acdoc
- 'nil
- (vla-get-activedocument (vlax-get-acad-object))
- )
- )
从结果来说,完全等同于
 -
- (eval '(defun LM:acdoc () (vla-get-activedocument (vlax-get-acad-object))))
也就是下面的语句:
 - (defun LM:acdoc nil
- (vla-get-activedocument (vlax-get-acad-object))
- )
也就是说 eval,eval的是对一个函数进行定义,仅仅是定义,但并未对这个函数求值。
2、但从效率来说,Lee的反而低了点,因为用了eval
所以 ,Lee的这段代码就等于下面的:
 -
- (defun LM:acdoc nil
- (defun LM:acdoc nil
- (vla-get-activedocument (vlax-get-acad-object))
- )
- (LM:acdoc)
- )
3、这这个函数粗一看,是递归的,递归没做处理,就会变成死循环,但是为何没有呢?
是因为 Lee 定义了这个名为 LM:acdoc的函数,结果在函数内部又重新定义了一下这个函数
所以函数返回的时候,用的却是函数里面的定义。
以一个简单的例子来说
 -
- (defun A ()
- (defun A ()
- (+ 1 1)
- )
- (A)
- )
我开始定义了一个名为A 的函数,在函数里面又调用了A ,如果在函数内没有重新定义A函数,这个函数将陷入死循环,很快LISP就会有错误提示:
vlide 出现硬错误 ***
已达内部堆栈限制 (模拟)
说明是递归函数没设置终止条件。但正是因为在函数里面重新定义了函数体,所以才避免的这样情况,最后执行的是在函数内的定义。
4、Lee 的本义是只是将下面的语句执行一次求值:
(vla-get-activedocument (vlax-get-acad-object))
但是达到效果了吗?没,
用户可以自行用断点运行,发现结果还是要进行求值,所以Lee的想法落空了。
因此,就这个函数来说,我个人观点认识是Lee的做法有点过了。
|