前言
在電腦程式中,資料存在於記憶體。變數本身不是資料,而是資料的標籤。電腦程式藉由變數存取資料。本文介紹在 Common Lisp 中使用變數的方式。
宣告全域變數 (Global Variable)
雖然 Common Lisp 是函數式語言,必要時還是可以使用全域變數來控制程式的狀態。使用 defvar 可宣告變數。
以下範例宣告全域變數 *v*
,其值為 5.0
:
(defvar *v* 5.0)
注意變數 *v*
的 *
(星號,asterisk) 也是變數的一部分。Common Lisp 對識別字 (identifier) 的建立規則比一般程式語言還寬鬆,詳見下文。
依照慣例,在 Common Lisp 中建立全域變數時,會在變數中加上一對 *
符號。雖然這沒有強制性,這是一種常見的風格。這種寫法讓別的 Common Lisp 一看就知道該變數是全域變數。
如果要更動變數的值,可以用 setq 指令。承上,我們修改全琙變數 *v*
的值:
(setq *v* 7.0)
在 Common Lisp 中,有數個內建的全域變數,用來調整程式的設置。像是 *load-verbose* 變數可用來控制載入 Lisp 命令稿時,是否要輸出文字訊息。
宣告局部變數 (Local Variable)
比起全域變數,寫 Common Lisp 程式時更常使用局部變數。局部變數對程式的影響僅限於特定指令所在處,不太會因不當修改造成 bug。
當我們需要局部變數,但不需要從該區域回傳值時,可以用 prog 指令。參考以下範例:
(prog ((x 3))
(write-line (princ-to-string x)))
相對來說,當我們需要從區域回傳值時,則會改用 let 指令。參考以下範例:
(let ((x 3)
(y 4))
(+ x y))
宣告常數 (Constant)
當我們希望變數的值在整個程式中固定不變時,可以用 defconstant 指令宣告常數,這時候 Common Lisp 編譯器會協助程式設計者檢查該變數是否有被修改到,並發出錯誤訊息。
例如,圓周率或歐拉數的值是固定不變的,就很適合宣告成常數。以下程式碼片段宣告歐拉數 (Euler's number):
(defconstant e 2.7182818284 "The base of natural logarithm")
Common Lisp 的識別字 (Identifier) 建立規則
在程式語言中,識別字是有特定意義的符號。除了程式語言內建的識別字外,程式設計者可藉由多種指令建立新的識別字。識別字可能代表變數、運算子、函式、類別、巨集等。Lisp 家族語言不嚴格區分運算子、函式、巨集等語法,比 Algol 家族語言 (註) 自由得多。
(註) 即 C 家族語言。
Common Lisp 的識別字的規則比其他程式語言寬鬆得多,其規則如下:
- 不是數字
- 不是套件名稱 (package marker) (註)
- 不全由
.
(dot) 組成
(註) 以 :
開頭的符號,如 :cl
。
實務上,大多數識別字會以小寫英文字母和 -
(hyphen) 組成。雖然 Common Lisp 不區分大小寫,以小寫英文字母撰寫程式碼比較容易閱讀。
以下是一些例子: