完美 发表于 2025-1-1 17:37:04

lisp自定义函数或变量名是否有较为通用的命名规则

本人刚入坑,想请问下编写lisp代码过程中自定义函数以及变量名是否有什么约定俗成或者对于系统学习lisp有益的的命名规则

e2002 发表于 2025-1-3 14:42:21

本帖最后由 e2002 于 2025-2-19 15:46 编辑

建议 AutoLISP编码的一般规范:
1. AutoLISP 提供的标准函数, 全小写 ,例如: initget , getfiled,polar ...
2. 对齐括号:一句代码,分多行时,结束的括号对齐开始括号,并单独写在一行(虽然有人认为这个多余,但实际上按这个规定写,能少很多错误,也容易看清楚代码结构):
   
(foo var0 value0
       var1 value1
);_对齐foo前面那个开始括号
3. 普通变量名称:
    3.1 一些长期一来,AutoLISP圈内习惯的如:图元名 en,图元表 el ,图元类型 etype 等,按习惯这么就好。
    3.2 repeat 循环变量,lambda变量,一般用单个英文字母,如果整形,一般 i,j,k,m,n;其他 x,y,z,u,v,w。
    3.2 匈牙利命名法,对于AutoLISP还是推荐使用(毕竟没有 VS 那样强劲的IDE辅助):
         按变量类别:rLength, iCount, sText, bIsLoked, lrAreas (l 表示 list,r表示 real); l_sSerial_ptCenter (list, 其中每个item为子list或者dotpair,例如:( ( "256" (24.3 28.7 0.0) ); ( ( "256" . (24.3 28.7 0.0))
    3.3 其他的普通变量,一般用简洁、准确的英语单词,Camal 或者 snake_mode 模式,例如 ptStart, rAngleFromXAxis , iTotalPages。
    3.4 使用了对象,方法:对象名称,建议与 C#一致。
         常用的习惯的如 acApp,acDoc,acSpace等;
         一般的对象,简单的可以直接全小写,例如 line,layer (因为vscode或者vlide对标准函数都有高亮显示,颜色与同位全小写的对象名称能显著的区分);
      对象特性或方法,一般写为: vla-get-CapWord,vla-Method , 例如 (vla-get-Count obj), (vla-GetBoundingBox obj 'ptMin 'ptMin);
    3.5 函数名称与子函数名称:与变量基本一致,建议采用 snake_Mode, 这样能一眼看出这是函数而不是变量,函数内定义的子函数,建议采用 "_"开头,这样能一眼看出这是内部使用的子函数,例如:(defun _mainProgram_internalFunction (par0 par1 / ...) ...         
4. 语句块格式:
    主要是 if,while, repeat, foreach,cond 这些:
          4.1 简单的if,可以直接一行:(if bFlag (_do_SomeThing var))
               如果有 else或者包含很多语句, 一般分开多行:
          (if (setq esl (entsel))
(progn
      (...)
      (...)
   );_progn, then
   (progn
      (...)
      (...)
   );_progn, else
);_fi

      4.2 AutoLISP 只有 while ,没有 do...while:
               要使用do...while,可以用:
            
(setq bLoop T)
   (while bloop
   (...)
   (if condition
       (setq bLoop nil);_在某种条件下,设置标记值bLoop= nil,用于退出while循环。
   );_fi
   (...)
   );_while
            

         4.3 repeat 适用与循环次数已知且不变的情况:
(repeat iCount
   (do_something ...)
       (...)
)            4.4 cond: 类似 C#中的 switch...case,但个人认为cond 比switch...case 要灵活多了,switch...case中的 case太死板了,而cond 中的各种条件,只需要条件语句的返回值 not nil 即可执行后面的一系列语句,且不需要写一堆 break。(cond
   ( (do_check_function0 var0) (do_something0)(do_something1 ...) (...) )
   ((do_check_function1 var1) (...) (...) (...) );_注意这里在条件判断语句之后可以有很多执行的语句,且不需要象if中那样必须用progn包起来,这一点比较符合习惯。
   ((conditons...) (...) (...) (...) )
);_cond

GEGEYANG88 发表于 2025-1-1 20:37:10

凭我的经验,玩LISP编程的时候,自定义函数都是英文名带un,局部变量都是英文名带er,大多情况能绕开CAD专用名,既方便阅读,又能有效避免冲突。譬如:angler,distancer,lisper。

llsheng_73 发表于 2025-1-1 17:39:31

本帖最后由 llsheng_73 于 2025-1-1 18:44 编辑

基本没有,不过如果有其它语言编程经验,可以用
没有就随便搞,只需要注意一点:尽量不要全局变量就行,但这一点可能很多例子里边根本没有顾及它,导致很多人都搞得全局变量满天飞,程序多了就该头痛了
另外一点:如果有些变量只是中间过渡使用,可以想法将一些语句封装成一个函数(哪怕这个函数只被调用一次),让那些临时过渡变量成为局部变量;或者适当嵌套语句,减少不必要的临时过渡变量,免得因为变量名过多把自己搞晕。。。

czb203 发表于 2025-1-1 18:06:14

llsheng_73 发表于 2025-1-1 17:39
基本没有,不过如果有其它语言编程经验,可以用
没有就随便搞,只需要注意一点:尽量不要全局变量就行,但 ...

程序不断的添加变量,搞到后面都乱了

llsheng_73 发表于 2025-1-1 18:39:17

czb203 发表于 2025-1-1 18:06
程序不断的添加变量,搞到后面都乱了

所以要搞局部变量,尽量把功能函数化,不要一个C:TT写完所有,那样哪怕全部搞成局部变量,自己在内部都能因为变量把自己搞晕,反正我看头一长串setq,连续无数临时过渡变量看着都头痛,可以最后真正只用到极少几个变量,但中间变量一大堆,那样还不如把表达式嵌套起来。。。

完美 发表于 2025-1-1 18:48:53

llsheng_73 发表于 2025-1-1 18:39
所以要搞局部变量,尽量把功能函数化,不要一个C:TT写完所有,那样哪怕全部搞成局部变量,自己在内部都能 ...

受教了,目前我就是这种情况,一个函数写到底,还是要有意识的把函数拆分成多个功能更加细化的函数。

飞雪神光 发表于 2025-1-1 23:19:31

还有不用中文和变量中包含 .

e2002 发表于 2025-1-3 23:19:44

本帖最后由 e2002 于 2025-1-3 23:29 编辑

关于局部变量: AutoLISP 与其他语言不同,只要你没有把变量名写在函数定义的那个内部函数变量列表中, 那么这个没写进去的变量就是全局变量:
(defun foo (par0 par1 ... / internal_var0 internal_var1...)
   (...)

通常,在一个完整的AutoLISP 程序中,不要出现全局变量。当然,由于AutoLISP后来提供了 编译的fas,vlx,支持了独立命名空间,所以fas,vlx程序中真有全局变量,也因为独立命名空间的存在,不会互相影响了。不过作为一个好的编程规则,还是建议大家,不要出现全局变量,真要有数据需要跨程序保存,有注册表,有xdata,Xrecord 等很多方法,再不济也可以把要保存的数据写到一个文件里。

还有要注意,使用了vla对象,最好要在使用对象之后,及时释放对象: (vlax-release-object objVlaObject)。

e2002 发表于 2025-1-3 23:34:19

编码中要注意尽量避免重复性的语句,刚开始写的时候还可以临时这么写,但程序的功能与逻辑在测试没问题之后,就要优化程序结构了,要提炼出子函数,替代那些繁琐、冗余的重复性的语句。代码重构与优化,是每一个coder必做的工作。特别是一些条件分支优化,循环中不必要的重复求值,重复读写,都需要发现并优化调整。
页: [1] 2
查看完整版本: lisp自定义函数或变量名是否有较为通用的命名规则