明经CAD社区

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
楼主: mayingjun

[讨论] Lee Mac大神为什么这样写vla容器的函数?

[复制链接]
 楼主| 发表于 2019-8-1 10:40:08 | 显示全部楼层
highflybir 发表于 2019-8-1 10:35
嗯,看来lee是对的,我再仔细看看eval那段.

非常感谢你的分析,我只是恍惚觉得这样写是为了一次求值。通过你的分析才去作测试,从而证实了这种猜想。
发表于 2019-8-1 10:59:24 | 显示全部楼层
多年以前就讨论过这个问题,但最终也没什么人能说清楚到底有什么必要那么写。
发表于 2019-8-1 11:05:49 | 显示全部楼层
本帖最后由 highflybir 于 2019-8-1 11:07 编辑

  1. (defun A nil
  2.   (eval
  3.     (list 'defun
  4.           'a
  5.           'nil
  6.           (setq i 0)
  7.           (repeat 10000 (setq i (1+ i)))
  8.           (princ i)
  9.     )
  10.   )
  11.   (a)
  12. )


我给出了上面的一段程序,从这个写法来说,看来,第一次求值后 ,第二次就不用再repeat了。
eval  list 和eval  ' 的效果的确不一样。  

点评

区别在:'((repeat 1000))不执行,(list (repeat 1000))执行。  发表于 2019-8-1 17:02
发表于 2019-8-1 11:09:38 | 显示全部楼层
但这有什么必要呢?下次用到这个a函数的时候,a函数是怎样的定义呢?
发表于 2019-8-1 11:15:28 | 显示全部楼层
ll_j 发表于 2019-8-1 11:09
但这有什么必要呢?下次用到这个a函数的时候,a函数是怎样的定义呢?

如果第一次求值是一件很耗时的事情的时候,就有必要了,就可以不必再求值,只要引用第一次求值的结果。
 楼主| 发表于 2019-8-1 11:26:01 | 显示全部楼层
本帖最后由 mayingjun 于 2019-8-1 11:27 编辑
highflybir 发表于 2019-8-1 11:15
如果第一次求值是一件很耗时的事情的时候,就有必要了,就可以不必再求值,只要引用第一次求值的结果。

对,list里面的东西,在eval之前就会被求值,再次运行就不会求值了。而'之内的东西,永远会被eval求值。虽然这种写法,和用一个全局变量相同,只不过是用了一个全局函数。但是弄清楚原理还是非常有必要的。
发表于 2019-8-1 11:36:52 | 显示全部楼层
(defun LM:acdoc ()
  (eval (list 'defun 'LM:acdoc '() (alert "a") (vla-get-activedocument (vlax-get-acad-object))))
  (alert "b")
  (LM:acdoc)
)
(LM:acdoc)

第1交执行会弹出 a 然后重新定义函数 再弹出b 然后在掉用函数 应该还会弹出1次 a ,为什么不就弹了
第2次执行什么都不弹出,为什么?直接就返回值了,既然没有弹出a,那a后面的也没有执行,值是怎么来的?
奇怪了
发表于 2019-8-1 11:41:57 | 显示全部楼层
哦  看懂了

(list 'defun 'LM:acdoc '() (alert "a") (vla-get-activedocument (vlax-get-acad-object)))
变成了这个
(DEFUN LM:ACDOC nil nil #<VLA-OBJECT IAcadDocument 0000000030636888>)
他没有用全局变量   他直接把值存在函数里了
发表于 2019-8-1 11:53:10 | 显示全部楼层
把defun 换成defun-q可能看得更清楚
譬如下面的这段,
  1. (defun A nil
  2.   (eval
  3.     (list 'DEFUN-q
  4.           'a
  5.           'nil
  6.           (setq i 0)
  7.           (repeat 10000 (setq i (1+ i)))
  8.           (princ i)
  9.     )
  10.   )
  11.   (a)
  12. )


$ A
#<USUBR @00000000598ead18 A>
_$ (a)
1000010000
_$ a
(nil 0 10000 10000)
_$

第一次加载函数的时候 ,A是一个函数, 然后 函数执行一次之后 , a函数就变成了变了。
最后的返回值是10000 而不是princ



发表于 2019-8-1 11:57:18 | 显示全部楼层
taoyi0727 发表于 2019-8-1 11:41
哦  看懂了

(list 'defun 'LM:acdoc '() (alert "a") (vla-get-activedocument (vlax-get-acad-object)) ...

你确定你看懂了,为什么不直接用变量储存Document对象?
您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋|手机版|CAD论坛|CAD教程|CAD下载|联系我们|关于明经|明经通道 ( 粤ICP备05003914号 )  
©2000-2023 明经通道 版权所有 本站代码,在未取得本站及作者授权的情况下,不得用于商业用途

GMT+8, 2025-5-18 15:23 , Processed in 0.158131 second(s), 19 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表