函式是一組一起執行任務的語句。
可以把程式碼放到單獨的函式。如何劃分程式碼之前不同的功能,但在邏輯上劃分通常是這樣每個函式執行特定的任務。
命名函式defun巨集用於定義函式。該函式的defun巨集需要三個引數:
函式名稱
函式的引數
函式的體
defun語法是:
(defun name (parameter-list) "Optional documentation string." body)
讓我們舉例說明概念,簡單的例子。
例子 1
讓我們編寫了一個名為averagenum,將列印四個數位的平均值的函式。我們將會把這些數位作為引數。
建立一個名為main.lisp一個新的原始碼檔案,並在其中輸入如下程式碼:
(defun averagenum (n1 n2 n3 n4) (/ ( + n1 n2 n3 n4) 4)) (write(averagenum 10 20 30 40))
當執行的程式碼,它返回以下結果:
25
範例 2
讓我們定義和呼叫函式,將計算出的圓的面積,圓的半徑被指定作為引數的函式。
建立一個名為main.lisp一個新的原始碼檔案,並在其中輸入如下程式碼:
(defun area-circle(rad) "Calculates area of a circle with given radius" (terpri) (format t "Radius: ~5f" rad) (format t "~%Area: ~10f" (* 3.141592 rad rad))) (area-circle 10)
當執行的程式碼,它返回以下結果:
請注意:
可以提供一個空的列表作為引數,這意味著函式沒有引數,該列表是空的,表示為()。
LISP還允許可選,多個和關鍵字引數。
文件字串描述了函式的目的。它與函式名相關聯,並且可以使用文件函式來獲得。
函式的主體可以包含任意數量的Lisp表示式。
在主體內的最後一個表示式的值返回函式的值。
還可以使用返回 - 從特殊的運算子函式返回一個值。
讓我們討論在簡要上述概念。點選以下連結,了解詳細資訊:
可以使用可選引數定義一個函式。要做到這一點,需要把符號與可選的可選引數的名稱之前。
我們將只是顯示它接收的引數的函式。
範例
建立一個名為main.lisp一個新的原始碼檔案,並在其中輸入如下程式碼:
(defun show-members (a b &optional c d) (write (list a b c d))) (show-members 1 2 3) (terpri) (show-members 'a 'b 'c 'd) (terpri) (show-members 'a 'b) (terpri) (show-members 1 2 3 4)
當執行程式碼,它返回以下結果:
(1 2 3 NIL) (A B C D) (A B NIL NIL) (1 2 3 4)
請注意,引數c和d是在上面的例子中,是可選引數。
有些函式需要採用可變數目的引數。
例如,我們使用格式化函式需要兩個必需的引數,資料流和控制字串。然而,該字串後,它需要一個可變數目的取決於要顯示的字串中的值的數目的引數。
同樣,+ 函式,或 * 函式也可以採取一個可變數目的引數。
可以提供這種可變數目的使用符號與其餘引數。
下面的例子說明了這個概念:
範例
建立一個名為main.lisp一個新的原始碼檔案,並在其中輸入如下程式碼:
(defun show-members (a b &rest values) (write (list a b values))) (show-members 1 2 3) (terpri) (show-members 'a 'b 'c 'd) (terpri) (show-members 'a 'b) (terpri) (show-members 1 2 3 4) (terpri) (show-members 1 2 3 4 5 6 7 8 9)
當執行程式碼,它返回以下結果:
(1 2 (3)) (A B (C D)) (A B NIL) (1 2 (3 4)) (1 2 (3 4 5 6 7 8 9))
關鍵字引數允許指定哪個值與特定的引數。
它使用的是 &key 符號表示。
當傳送的值到該函式必須先於值 :parameter-name.
下面的例子說明了這個概念。
例子
建立一個名為main.lisp一個新的原始碼檔案,並在其中輸入如下程式碼:
(defun show-members (&key a b c d ) (write (list a b c d))) (show-members :a 1 :c 2 :d 3) (terpri) (show-members :a 'p :b 'q :c 'r :d 's) (terpri) (show-members :a 'p :d 'q) (terpri) (show-members :a 1 :b 2)
當執行程式碼,它返回以下結果:
(1 NIL 2 3) (P Q R S) (P NIL NIL Q) (1 2 NIL NIL)
預設情況下,在LISP函式返回最後一個表示式作為返回值的值。下面的例子將證明這一點。
範例 1
建立一個名為main.lisp一個新的原始碼檔案,並在其中輸入如下程式碼:
(defun add-all(a b c d) (+ a b c d)) (setq sum (add-all 10 20 30 40)) (write sum) (terpri) (write (add-all 23.4 56.7 34.9 10.0))
當執行程式碼,它返回以下結果:
100 125.0
但是,可以使用返回- 從特殊的操作符立即從函式返回任何值。
範例 2
建立一個名為main.lisp一個新的原始碼檔案,並在其中輸入如下程式碼:
(defun myfunc (num) (return-from myfunc 10) num) (write (myfunc 20))
當執行程式碼,它返回以下結果:
10
更改一點點程式碼:
(defun myfunc (num) (return-from myfunc 10) write num) (write (myfunc 20))
它仍然返回:
10
有時,可能需要一個函式只在一個程式中的位置和功能是如此的微不足道,可能不給它一個名稱,也可以不喜歡它儲存在符號表中,寧可寫一個未命名或匿名函式。
LISP允許編寫評估計算在程式中遇到的匿名函式。這些函式被稱為Lambda函式。
可以使用lambda表示式建立這樣的功能。lambda表示式語法如下:
(lambda (parameters) body)
lambda形式可以不進行評估計算,它必須出現只有在LISP希望找到一個函式。
範例
建立一個名為main.lisp一個新的原始碼檔案,並在其中輸入如下程式碼:
(write ((lambda (a b c x) (+ (* a (* x x)) (* b x) c)) 4 2 9 3))
當執行程式碼,它返回以下結果:
51
對映函式是一組函式,可以連續地施加於元件中的一個或多個列表。應用這些功能列表的結果被放置在一個新的列表,而新的列表返回。
例如,mapcar函式處理的一個或多個列表連續元素。
在mapcar函式的第一個引數應該是一個函式,其餘的引數是該函式的應用列表(次)。
函式的引數被施加到連續的元素,結果為一個新構造的列表。如果引數列表是不相等的長度,然後對映的過程停止在達到最短的列表的末尾。結果列表將元素作為最短輸入列表的數目相同。
範例 1
讓我們從一個簡單的例子和數位1 新增到每個列表的元素( 23 34 45 56 67 78 89)。
建立一個名為main.lisp一個新的原始碼檔案,並在其中輸入如下程式碼:
(write (mapcar '1+ '(23 34 45 56 67 78 89)))
當執行程式碼,它返回以下結果:
(24 35 46 57 68 79 90)
範例 2
讓我們寫這將多維資料集列表中的元素的函式。讓我們用一個lambda函式用於計算數位的立方。
建立一個名為main.lisp一個新的原始碼檔案,並在其中輸入如下程式碼:
(defun cubeMylist(lst) (mapcar #'(lambda(x) (* x x x)) lst)) (write (cubeMylist '(2 3 4 5 6 7 8 9)))
當執行程式碼,它返回以下結果:
(8 27 64 125 216 343 512 729)
範例 3
建立一個名為main.lisp一個新的原始碼檔案,並在其中輸入如下程式碼: