大全分類手冊:從數(shù)學(xué)運(yùn)算到選擇集操作的核心函數(shù)速查指南)
簡介《LISP函數(shù)大全分類手冊》是一份面向AutoLISP初學(xué)者與CAD二次開發(fā)者的函數(shù)速查資料以PDF形式系統(tǒng)梳理了AutoLISP常用函數(shù)幫助讀者在編寫和調(diào)試LISP程序時快速定位語法與用途。資源包共1個PDF文件大小約47KB輕量便攜適合隨時查閱。手冊按功能劃分為數(shù)學(xué)運(yùn)算、檢驗(yàn)與邏輯運(yùn)算、轉(zhuǎn)換運(yùn)算、列表處理等模塊逐條列出函數(shù)原型與返回值說明例如數(shù)學(xué)運(yùn)算中的加減乘除、取整、最大公約數(shù)邏輯運(yùn)算中的比較與位運(yùn)算轉(zhuǎn)換運(yùn)算中的角度、字符串與實(shí)數(shù)互轉(zhuǎn)以及列表處理中的car、cdr、cons、mapcar等核心操作并延伸至字符串、文件、等待輸入與幾何運(yùn)算等常用函數(shù)。目前已有765人學(xué)習(xí)下載內(nèi)容覆蓋AutoLISP編程基礎(chǔ)可作為案頭工具書幫助讀者理解函數(shù)語義、積累調(diào)用經(jīng)驗(yàn)進(jìn)而提升CAD環(huán)境下的程序編寫效率與靈活性。1. 搞懂 LISP 函數(shù)為什么一串括號能指揮整個繪圖流程很多人第一次看到 LISP 代碼腦子里冒出的第一個念頭是這一堆括號到底在干什么比如( 1 2 3)看起來像某種加密過的算式實(shí)際上它就是 1 加 2 加 3 的意思。LISP 的全稱是 List Processing翻譯過來叫“列表處理”它的核心思想非常樸素——代碼本身就是數(shù)據(jù)數(shù)據(jù)也是代碼所有東西都用括號包成一個列表來表達(dá)。打個比方LISP 的括號就像廚房里的備菜盤。每個盤子里放著食材和調(diào)料廚師按盤子上的順序依次處理。( 1 2)這個盤子里裝的是“加法操作、數(shù)字 1、數(shù)字 2”LISP 引擎看到盤子就知道該做加法。這種“操作符放最前面”的寫法叫前綴表達(dá)式和數(shù)學(xué)課上寫的1 2順序不同但邏輯一樣。AutoLISP 是嵌入在 CAD 軟件里的 LISP 方言專門用來做繪圖自動化和批量處理。這份《LISP函數(shù)大全分類手冊》把 AutoLISP 的函數(shù)按功能分成十九個大類從數(shù)學(xué)運(yùn)算到對象處理、從選擇集操作到內(nèi)存管理基本覆蓋了日常寫腳本會用到的全部工具。搞懂這些函數(shù)的分類邏輯比死記硬背每個函數(shù)的參數(shù)有用得多——因?yàn)槟阒烙龅绞裁磫栴}該去哪個抽屜里找工具。2. 數(shù)學(xué)與邏輯函數(shù)LISP 的算盤和判官2.1 數(shù)學(xué)運(yùn)算函數(shù)到底在算什么數(shù)學(xué)函數(shù)是 LISP 里最沒有理解門檻的一類因?yàn)樗鼈兊拿趾凸δ軒缀跻灰粚?yīng)。( 數(shù)值 數(shù)值...)做累加(- 數(shù)值 數(shù)值...)做減法(* 數(shù)值 數(shù)值...)做乘法(/ 數(shù)值 數(shù)值...)做除法。注意一個細(xì)節(jié)減法和除法都是“第一個數(shù)減/除以后面所有的數(shù)”不是兩兩配對。比如(- 10 3 2)的結(jié)果是 5先算 10 減 3 得 7再減 2 得 5。除了四則運(yùn)算手冊里還列了一批“單數(shù)值操作”函數(shù)。(abs 數(shù)值)取絕對值(fix 數(shù)值)把實(shí)數(shù)截?cái)喑烧麛?shù)(sqrt 數(shù)值)求平方根(exp 數(shù)值)算自然指數(shù)(log 數(shù)值)算自然對數(shù)。這些函數(shù)在寫幾何計(jì)算腳本時出場率極高比如算兩點(diǎn)距離、判斷坐標(biāo)是否在某個范圍內(nèi)。三角函數(shù)值得單獨(dú)提一句。(sin 角度)和(cos 角度)的參數(shù)單位是弧度不是角度。很多人第一次用的時候傳了 90 進(jìn)去以為能算出 1結(jié)果得到一個約等于 0.894 的數(shù)——因?yàn)?90 弧度早就繞了好幾圈了。正確做法是用pi常數(shù)來換算比如 90 度要寫成(/ pi 2)。;; 計(jì)算 60 度角的正弦值 ;; 先把角度轉(zhuǎn)成弧度60 * pi / 180 (sin (* 60 (/ pi 180))) ;; 返回約 0.866這段代碼里pi是 AutoLISP 內(nèi)置的常數(shù)約等于 3.1415926。(/ pi 180)算出每度對應(yīng)的弧度值再乘以 60 就得到 60 度的弧度表示。這種寫法在需要精確控制角度的繪圖腳本里非常常見。(gcd 數(shù)值1 數(shù)值2)求最大公約數(shù)(rem 數(shù)值1 數(shù)值2)求余數(shù)(max ...)和(min ...)在一堆數(shù)里挑最大最小。這些函數(shù)單獨(dú)看都很簡單但組合起來能解決不少實(shí)際問題。比如判斷一個數(shù)是不是偶數(shù)可以用( (rem n 2) 0)比如把任意角度規(guī)范到 0 到 360 度之間可以用rem配合條件判斷。2.2 邏輯判斷LISP 怎么分辨真假LISP 里的“真”和“假”跟很多語言不太一樣。它用T表示真用nil表示假而且nil同時兼任“空列表”的角色。這意味著任何返回空列表的操作在邏輯判斷里都等同于“假”。這個設(shè)計(jì)初看有點(diǎn)怪但用久了會發(fā)現(xiàn)它讓代碼變得很緊湊。比較函數(shù)是邏輯判斷的基礎(chǔ)。( 表達(dá)式1 表達(dá)式2)判斷相等( ...)判斷小于( ...)判斷大于( ...)和( ...)分別判斷小于等于和大于等于。這些函數(shù)不僅能比較數(shù)字還能比較字符串。比如( abc abc)返回T( apple banana)也返回T因?yàn)樽址容^走的是字典序。(and 表達(dá)式1 表達(dá)式2...)做邏輯與運(yùn)算所有表達(dá)式都為真時才返回真。(eq 表達(dá)式1 表達(dá)式2)和(equal 表達(dá)式1 表達(dá)式2 [差量])是一對容易搞混的函數(shù)。eq比較的是“是不是同一個對象”equal比較的是“內(nèi)容是不是一樣”。舉個例子兩個分別創(chuàng)建的列表(list 1 2)和(list 1 2)用eq比較返回nil用equal比較返回T。equal還支持一個可選的差量參數(shù)用于實(shí)數(shù)比較時容忍微小誤差——這在浮點(diǎn)運(yùn)算里非常實(shí)用因?yàn)橛?jì)算機(jī)算出來的 0.1 加 0.2 不一定精確等于 0.3。(boole 函數(shù) 整數(shù) 整數(shù)...)做位運(yùn)算(~ 數(shù)值)做按位取反。這兩個函數(shù)在寫底層工具或者處理二進(jìn)制標(biāo)志位時才會用到日常繪圖腳本里出現(xiàn)頻率不高但知道它們存在能讓你在遇到位操作需求時不至于抓瞎。3. 列表處理函數(shù)LISP 的看家本領(lǐng)3.1 列表的拆與裝列表是 LISP 的命根子幾乎所有數(shù)據(jù)都用列表來表示。一個三維坐標(biāo)點(diǎn)是列表(x y z)一條線的信息是列表((起點(diǎn)) (終點(diǎn)))圖元的數(shù)據(jù)更是嵌套了好幾層的列表。所以列表處理函數(shù)是這份手冊里最值得花時間理解的部分。(car 列表)取列表的第一個元素(cadr 列表)取第二個(caddr 列表)取第三個。這三個函數(shù)在 CAD 腳本里幾乎無處不在因?yàn)樽鴺?biāo)點(diǎn)就是三元素列表car拿 X 坐標(biāo)cadr拿 Y 坐標(biāo)caddr拿 Z 坐標(biāo)。(cdr 列表)返回去掉第一個元素之后的剩余部分常用來遍歷列表。(cons 新元素 列表)把新元素塞到列表頭部(append 列表1 列表2...)把多個列表首尾拼接成一個。這兩個函數(shù)的區(qū)別在于cons的第二個參數(shù)必須是列表結(jié)果是新元素成為列表的第一個append的所有參數(shù)都必須是列表結(jié)果是所有元素合并。比如(cons 1 (list 2 3))得到(1 2 3)(append (list 1) (list 2 3))也得到(1 2 3)但(cons 1 2)會報(bào)錯因?yàn)?2 不是列表。(list 元素1 元素2...)把散落的元素打包成一個列表(length 列表)數(shù)一數(shù)列表里有幾個元素(reverse 列表)把列表順序顛倒過來(nth n 列表)取出第 n 個元素從 0 開始數(shù)。這些函數(shù)組合起來能完成大部分列表操作需求。;; 從坐標(biāo)點(diǎn)列表中提取所有 X 坐標(biāo) ;; 假設(shè) points 是 ((1 2 0) (3 4 0) (5 6 0)) (mapcar car points) ;; 返回 (1 3 5)mapcar是列表處理里的“批量處理器”。它把函數(shù)依次應(yīng)用到每個列表的對應(yīng)元素上返回一個新列表。上面這段代碼用car函數(shù)批量提取每個點(diǎn)的第一個元素一行就完成了遍歷。mapcar后面可以跟多個列表函數(shù)會按位置依次取參。比如(mapcar (1 2) (10 20))返回(11 22)相當(dāng)于把兩個列表對應(yīng)位置的元素相加。3.2 查找、替換與遍歷(assoc 關(guān)鍵元素 聯(lián)合列表)在“關(guān)聯(lián)列表”里查找匹配項(xiàng)。關(guān)聯(lián)列表是一種特殊的嵌套列表結(jié)構(gòu)每個子列表的第一個元素是鍵后面跟著值。比如((name A) (age 20))就是一個關(guān)聯(lián)列表(assoc name ...)會返回(name A)。這種結(jié)構(gòu)在存儲配置信息、圖元屬性時非常常用。(member 關(guān)鍵元素 列表)從列表里找到關(guān)鍵元素第一次出現(xiàn)的位置返回從該位置到末尾的子列表。如果沒找到就返回nil。(subst 新項(xiàng) 舊項(xiàng) 列表)把列表中所有等于舊項(xiàng)的元素替換成新項(xiàng)返回替換后的新列表。注意subst是“全量替換”列表里所有匹配的舊項(xiàng)都會被換掉。(foreach 名稱 列表 表達(dá)式)是遍歷列表的專用工具。它把列表里的每個元素依次賦值給名稱然后執(zhí)行表達(dá)式。和mapcar的區(qū)別在于mapcar收集每次執(zhí)行的結(jié)果組成新列表返回foreach不收集結(jié)果純粹為了執(zhí)行副作用比如打印信息、修改外部變量。選擇哪個取決于你是要“得到一個新列表”還是“對每個元素做一件事”。(listp 元素)判斷一個東西是不是列表返回T或nil。這個函數(shù)在寫遞歸處理嵌套列表的代碼時是必備的守衛(wèi)條件——先判斷是不是列表再決定要不要繼續(xù)往里拆。4. 轉(zhuǎn)換、字符串與輸入函數(shù)數(shù)據(jù)在 LISP 里怎么變形4.1 類型轉(zhuǎn)換數(shù)字和文字之間的翻譯官LISP 是弱類型語言但這不意味著類型不重要。很多時候你需要把用戶輸入的字符串變成數(shù)字才能計(jì)算或者把計(jì)算結(jié)果變成字符串才能顯示。轉(zhuǎn)換函數(shù)就是干這個的。(atof 字符串)把字符串轉(zhuǎn)成實(shí)數(shù)(atoi 字符串)把字符串轉(zhuǎn)成整數(shù)(itoa 整數(shù))把整數(shù)轉(zhuǎn)成字符串(rtos 數(shù)值 模式 [精度])把實(shí)數(shù)轉(zhuǎn)成字符串并控制格式。rtos的模式參數(shù)決定輸出格式模式 1 是科學(xué)計(jì)數(shù)法模式 2 是十進(jìn)制模式 3 是工程格式模式 4 是建筑格式模式 5 是分?jǐn)?shù)格式。精度參數(shù)控制小數(shù)點(diǎn)后保留幾位。角度轉(zhuǎn)換有一對專用函數(shù)。(angtof 字符串 [模式])把角度字符串轉(zhuǎn)成實(shí)數(shù)弧度(angtos 角度 [模式 [精度]])把弧度值轉(zhuǎn)成角度字符串。這兩個函數(shù)在處理用戶輸入的角度值時非常方便因?yàn)橛脩袅?xí)慣用“度”來思考而 LISP 內(nèi)部用弧度計(jì)算。(cvunit 數(shù)值 原始單位 轉(zhuǎn)換單位)做單位換算換算規(guī)則來自acad.nut文件。比如把英寸轉(zhuǎn)成毫米、把度轉(zhuǎn)成弧度。(trans 點(diǎn) 原位置 新位置 [位移])做坐標(biāo)系統(tǒng)轉(zhuǎn)換把點(diǎn)從一個坐標(biāo)系轉(zhuǎn)到另一個坐標(biāo)系。這個函數(shù)在寫涉及多個坐標(biāo)系的腳本時是剛需比如把用戶坐標(biāo)系里的點(diǎn)轉(zhuǎn)到世界坐標(biāo)系。;; 把用戶輸入的字符串 3.14 轉(zhuǎn)成實(shí)數(shù)并計(jì)算平方 ;; 假設(shè)用戶輸入存在變量 input-str 中 (setq input-str 3.14) (setq num (atof input-str)) (setq result (* num num)) ;; result 約等于 9.8596這段代碼展示了典型的“輸入-轉(zhuǎn)換-計(jì)算”流程。atof把字符串變成實(shí)數(shù)然后才能參與乘法運(yùn)算。如果跳過轉(zhuǎn)換直接對字符串做乘法LISP 會報(bào)錯。4.2 字符串處理與文件讀寫字符串函數(shù)處理文本數(shù)據(jù)。(strlen 字符串)返回字符個數(shù)(strcat 字符串1 字符串2...)把多個字符串拼接成一個(substr 字符串 起始 長度)從指定位置截取指定長度的子串(strcase 字符串 [字樣])轉(zhuǎn)換大小寫。(ascii 字符串)返回第一個字符的 ASCII 碼(chr 整數(shù))返回整數(shù)對應(yīng)的 ASCII 字符。(wcmatch 字符串 格式)做通配符匹配支持*和?等通配符。比如(wcmatch hello.lsp *.lsp)返回T用來判斷文件名是否符合某種模式。這個函數(shù)在批量處理文件時很有用。文件操作函數(shù)包括(open 文件名 模式)打開文件、(close 文件名)關(guān)閉文件、(read-line [文件代碼])讀一行、(write-line 字符串 [文件代碼])寫一行。模式參數(shù)用r表示讀取w表示寫入a表示追加。文件代碼是open返回的句柄后續(xù)讀寫操作都靠它來指定目標(biāo)文件。(read 字符串)把字符串解析成 LISP 數(shù)據(jù)。比如(read (1 2 3))返回列表(1 2 3)。這個函數(shù)在解析配置文件或者處理序列化數(shù)據(jù)時很有用。4.3 等待輸入讓腳本和用戶對話輸入函數(shù)讓腳本暫停執(zhí)行等待用戶提供數(shù)據(jù)。(getpoint [基點(diǎn)] [提示])請求用戶點(diǎn)選一個點(diǎn)(getdist [基點(diǎn)] [提示])請求輸入距離(getint [提示])請求整數(shù)(getreal [提示])請求實(shí)數(shù)(getstring [提示])請求字符串(getangle [基點(diǎn)] [提示])請求角度(getcorner 基點(diǎn) [提示])請求矩形對角點(diǎn)。這些函數(shù)的參數(shù)都是可選的。如果不提供提示信息CAD 命令行會顯示默認(rèn)提示。如果提供了基點(diǎn)用戶點(diǎn)選時會顯示一條從基點(diǎn)到當(dāng)前光標(biāo)的橡皮筋線方便定位。(initget [位] 字符串)用來限制下一次getxxx函數(shù)的有效輸入。位參數(shù)控制是否允許空輸入、零、負(fù)數(shù)等字符串參數(shù)列出允許的關(guān)鍵詞。比如(initget 1 Yes No)表示下一次輸入必須是非空值且只能是 Yes 或 No。這個函數(shù)在寫交互式腳本時能有效防止用戶亂輸入導(dǎo)致程序崩潰。(getkword [提示])專門用來獲取關(guān)鍵詞輸入配合initget使用。用戶輸入的關(guān)鍵詞會以字符串形式返回。5. 幾何、對象與選擇集LISP 怎么操作圖形5.1 幾何計(jì)算函數(shù)幾何函數(shù)處理點(diǎn)、線、角度、距離這些圖形基本元素。(angle 點(diǎn)1 點(diǎn)2)返回兩點(diǎn)連線的角度弧度(distance 點(diǎn)1 點(diǎn)2)返回兩點(diǎn)距離(polar 基點(diǎn) 弧度 距離)按極坐標(biāo)方式從基點(diǎn)出發(fā)走指定距離和角度得到新點(diǎn)(inters 點(diǎn)1 點(diǎn)2 點(diǎn)3 點(diǎn)4 [模式])求兩條線的交點(diǎn)。(osnap 點(diǎn) 模式字符串)按照對象捕捉模式取得精確坐標(biāo)。模式字符串可以是end端點(diǎn)、mid中點(diǎn)、cen圓心、int交點(diǎn)等。這個函數(shù)在寫需要精確對齊的腳本時非常關(guān)鍵因?yàn)橛脩羰髽?biāo)點(diǎn)選的位置往往有偏差osnap能自動吸附到精確位置。(textbox 對象列表)返回文字對象的兩個對角點(diǎn)坐標(biāo)用來計(jì)算文字占用的空間。這個函數(shù)在寫自動排版或者檢查文字是否重疊的腳本時會用到。;; 計(jì)算兩點(diǎn)之間的距離和角度 (setq p1 (0 0 0)) (setq p2 (3 4 0)) (setq dist (distance p1 p2)) ;; 返回 5.0 (setq ang (angle p1 p2)) ;; 返回約 0.9273 弧度 ;; 用 polar 從 p1 出發(fā)走 dist 距離、ang 角度應(yīng)該回到 p2 (polar p1 ang dist) ;; 返回 (3.0 4.0 0.0)這段代碼展示了distance、angle、polar三個函數(shù)的配合關(guān)系。polar本質(zhì)上是angle和distance的逆運(yùn)算——已知起點(diǎn)、方向和距離求終點(diǎn)。5.2 對象處理與選擇集對象處理函數(shù)直接操作圖形數(shù)據(jù)庫里的圖元。(entget 對象名稱)取出圖元的信息列表里面包含圖元類型、圖層、顏色、坐標(biāo)等所有屬性。(entmod 對象列表)把修改后的信息列表寫回圖元實(shí)現(xiàn)修改圖形。(entmake 對象列表)創(chuàng)建新圖元(entdel 對象名稱)刪除圖元(entnext [對象名稱])找下一個圖元(entlast)找最后一個圖元。(entsel [提示])請求用戶選取一個圖元返回包含圖元名稱和選點(diǎn)坐標(biāo)的列表。(nentsel [提示])和(nentselp [提示] [點(diǎn)])用于選取塊內(nèi)部的子圖元返回的信息更詳細(xì)。選擇集函數(shù)批量處理圖元。(ssget [模式] [點(diǎn)1] [點(diǎn)2])創(chuàng)建選擇集模式參數(shù)可以是W窗口包含、C交叉窗口、X過濾器等。(ssadd [對象名稱] [選擇集])把圖元加入選擇集(ssdel 對象名稱 選擇集)從選擇集移除圖元(sslength 選擇集)返回選擇集中的圖元數(shù)量(ssname 選擇集 索引值)按索引取出圖元名稱。(ssget X [過濾列表])是使用頻率最高的選擇集函數(shù)之一。過濾列表用關(guān)聯(lián)列表的形式指定篩選條件比如((0 . LINE))表示只選直線((8 . WALLS))表示只選 WALLS 圖層上的圖元。多個條件可以組合實(shí)現(xiàn)精確篩選。5.3 符號表與查詢控制符號表函數(shù)訪問圖形數(shù)據(jù)庫里的全局設(shè)置。(tblsearch 符號表名稱 符號)在指定符號表中查找符號(tblnext 符號表名稱 [T])遍歷符號表。有效的符號表名稱包括LAYER圖層、LTYPE線型、STYLE文字樣式、BLOCK塊等。查詢控制函數(shù)包括(getvar 系統(tǒng)變量)讀取系統(tǒng)變量值(setvar 系統(tǒng)變量 值)設(shè)置系統(tǒng)變量值(getenv 環(huán)境變量)讀取環(huán)境變量(findfile 文件名)查找文件路徑(getfiled 標(biāo)題 內(nèi)定檔名 擴(kuò)展名 旗號)彈出文件選擇對話框。(command AutoCAD命令 ...)是重量級函數(shù)直接在 LISP 里調(diào)用 CAD 原生命令。比如(command LINE (0 0) (10 10) )相當(dāng)于在命令行輸入畫線命令并指定兩個端點(diǎn)。這個函數(shù)讓 LISP 腳本能復(fù)用 CAD 的所有內(nèi)置功能是自動化繪圖的萬能鑰匙。6. 流程控制與函數(shù)定義讓 LISP 腳本活起來6.1 判斷與循環(huán)(if 比較式 表達(dá)式1 [表達(dá)式2])是最基本的條件判斷。比較式為真執(zhí)行表達(dá)式1否則執(zhí)行表達(dá)式2如果提供了的話。(cond (比較式1 表達(dá)式1) (比較式2 表達(dá)式2) ...)是多分支判斷依次檢查每個比較式執(zhí)行第一個為真的分支。(progn 表達(dá)式1 表達(dá)式2...)把多個表達(dá)式打包成一個常配合if和cond使用因?yàn)檫@兩個函數(shù)的分支只能寫一個表達(dá)式用progn就能塞進(jìn)去多個。(repeat 次數(shù) [表達(dá)式...])重復(fù)執(zhí)行指定次數(shù)(while 比較式 表達(dá)式...)在條件為真時反復(fù)執(zhí)行。while是寫不確定次數(shù)循環(huán)的標(biāo)準(zhǔn)工具比如遍歷一個列表直到取完為止。;; 用 while 遍歷列表并累加所有數(shù)字 (setq nums (1 2 3 4 5)) (setq total 0) (while nums (setq total ( total (car nums))) (setq nums (cdr nums)) ) ;; total 最終為 15這段代碼展示了 LISP 里最經(jīng)典的列表遍歷模式用car取頭部元素用cdr去掉頭部循環(huán)直到列表為空nil在條件判斷里為假。雖然foreach和mapcar更簡潔但理解這種底層遍歷方式有助于看懂老代碼。6.2 自定義函數(shù)與錯誤處理(defun 名稱 自變量列表 表達(dá)式...)定義自定義函數(shù)。這是 LISP 編程的核心——把重復(fù)的邏輯封裝成函數(shù)需要時調(diào)用即可。(lambda 自變量 表達(dá)式)定義匿名函數(shù)通常直接傳給mapcar或apply使用不需要單獨(dú)命名。(apply 功能函數(shù) 列表)把函數(shù)應(yīng)用到列表上相當(dāng)于把列表展開成參數(shù)列表再調(diào)用函數(shù)。(eval 表達(dá)式)執(zhí)行一個表達(dá)式并返回結(jié)果用于動態(tài)執(zhí)行代碼。(quote 表達(dá)式)或簡寫表達(dá)式阻止表達(dá)式被求值直接返回表達(dá)式本身。錯誤處理方面(*error* 字符串)定義錯誤處理函數(shù)當(dāng)程序出錯時自動調(diào)用。(alert 字符串)彈出警告對話框。(exit)和(quit)強(qiáng)制退出程序。(trace 函數(shù)...)和(untrace 函數(shù)...)設(shè)置和解除函數(shù)追蹤標(biāo)記用于調(diào)試。(setq 符號1 表達(dá)式1 [符號2 表達(dá)式2]...)是最常用的賦值函數(shù)把表達(dá)式的值賦給符號。(set 符號 表達(dá)式)功能類似但符號需要帶引號。(type 元素)返回元素的數(shù)據(jù)類型(boundp 表達(dá)式)判斷符號是否有值(null 元素)判斷元素是否為nil(numberp 元素)判斷是否為數(shù)字(zerop 元素)判斷是否為零(minusp 元素)判斷是否為負(fù)。7. 常見誤區(qū)這些函數(shù)名字很像用錯了就翻車7.1 eq 和 equal 到底差在哪這是 LISP 初學(xué)者最容易踩的坑。eq比較的是“兩個東西是不是同一個對象”equal比較的是“兩個東西的內(nèi)容是不是一樣”。對于數(shù)字和字符串兩者行為基本一致。但對于列表差別就出來了兩個分別用list創(chuàng)建的相同列表eq返回nilequal返回T。為什么會有這個區(qū)別因?yàn)?LISP 里列表是引用類型每次list調(diào)用都會在內(nèi)存里新建一個對象。eq看的是內(nèi)存地址equal看的是內(nèi)容。日常寫腳本時比較列表內(nèi)容用equal幾乎總是對的用eq比較列表基本都會翻車。7.2 car/cdr 和 first/rest 是一回事嗎AutoLISP 里car和cdr是標(biāo)準(zhǔn)函數(shù)first和rest在某些 LISP 方言里是它們的別名。但在 AutoLISP 里first和rest并不是內(nèi)置函數(shù)直接用會報(bào)錯。所以看到別的 LISP 代碼里用first和rest搬到 AutoLISP 里要改成car和cdr。另外cadr不是“cdr 的 car”而是“car 的 cdr 的 car”——從右往左讀先cdr去掉第一個元素再car取新列表的第一個元素也就是原列表的第二個元素。同理caddr是取第三個元素。這種命名規(guī)則可以擴(kuò)展到四層比如cadadr但超過三層可讀性就很差了。7.3 subst 和 entmod 都能改數(shù)據(jù)什么時候用哪個subst是純列表操作函數(shù)它返回一個新列表不修改原列表也不涉及圖形數(shù)據(jù)庫。entmod是圖形數(shù)據(jù)庫操作函數(shù)它把修改后的圖元信息列表寫回?cái)?shù)據(jù)庫直接改變屏幕上的圖形。如果你只是想處理一個普通列表數(shù)據(jù)用subst。如果你想修改圖形中某個圖元的屬性比如改顏色、改圖層需要先用entget取出信息列表用subst替換要改的字段再用entmod寫回。兩者是配合關(guān)系不是替代關(guān)系。7.4 getpoint 和 osnap 都能取點(diǎn)區(qū)別在哪getpoint是交互函數(shù)暫停程序等待用戶用鼠標(biāo)點(diǎn)選或鍵盤輸入坐標(biāo)。它返回的是用戶實(shí)際點(diǎn)選的位置可能有偏差。osnap是計(jì)算函數(shù)它不暫停程序而是根據(jù)給定的參考點(diǎn)和捕捉模式計(jì)算出一個精確的捕捉點(diǎn)。典型用法是先用getpoint讓用戶大致點(diǎn)一下再用osnap把那個點(diǎn)吸附到最近的端點(diǎn)或中點(diǎn)上。如果直接用getpoint的返回值作為繪圖坐標(biāo)畫出來的線可能沒有精確對齊。7.5 setq 和 set 看起來一樣為什么有兩個(setq 符號 表達(dá)式)的第一個參數(shù)不需要引號LISP 自動把它當(dāng)作符號名處理。(set 符號 表達(dá)式)的第一個參數(shù)需要求值所以通常要寫成(set 符號 表達(dá)式)。功能上兩者都能賦值但setq更簡潔是日常首選。set存在的意義在于它的第一個參數(shù)可以是變量——比如(set var-name value)可以根據(jù)var-name里存的符號名來動態(tài)賦值。這種動態(tài)賦值場景很少見但需要時只有set能做到。8. 什么時候該翻這本手冊什么時候別硬套這份《LISP函數(shù)大全分類手冊》最直接的用法是當(dāng)字典查。寫腳本時突然想不起來某個功能的函數(shù)名按分類翻到對應(yīng)章節(jié)掃一眼比在搜索引擎里大海撈針快得多。比如你需要做字符串大小寫轉(zhuǎn)換翻到“字符串處理”章節(jié)一眼就能看到strcase。但手冊不是教程它不會告訴你“寫一個自動標(biāo)注腳本需要哪幾步”。如果你完全沒寫過 LISP光看函數(shù)列表會一頭霧水——你知道每個函數(shù)干什么但不知道怎么把它們串起來解決實(shí)際問題。這種情況下更好的路徑是先找一個簡單的完整腳本例子跑通一遍理解基本結(jié)構(gòu)再回頭翻手冊查漏補(bǔ)缺。另一個需要注意的是版本差異。AutoLISP 在不同版本的 CAD 軟件里功能有增減手冊里列的函數(shù)大部分是長期穩(wěn)定的核心函數(shù)但涉及 3D 渲染、數(shù)據(jù)庫連接的那些外部定義函數(shù)可能因版本和安裝配置不同而表現(xiàn)不一致。遇到這類函數(shù)報(bào)錯先確認(rèn)當(dāng)前環(huán)境是否支持別急著懷疑自己代碼寫錯了。我自己的習(xí)慣是寫新腳本之前先翻一遍相關(guān)分類把可能用到的函數(shù)在紙上列出來標(biāo)上參數(shù)和返回值然后再動手寫。這個習(xí)慣幫我省了很多來回查文檔的時間。有一次寫批量改圖層的腳本我本來打算用while循環(huán)遍歷選擇集翻手冊時發(fā)現(xiàn)ssname配合sslength用repeat更直接少寫了好幾行代碼。希望這份手冊也能幫你少走一些彎路。本文還有配套的精品資源點(diǎn)擊獲取