一千萬個為什麽

搜索

如何在Emacs Lisp中創建臨時函數

我正在對一堆函數進行一些繁瑣的調用,但參數將在運行時確定。我寫了一個簡單的函數來保持我的代碼DRY,但是給它一個名字是不必要的。我不在其他任何地方使用此功能。

我試圖按照我在Scheme中的方式進行,但是我得到了 void-function 錯誤:

(let ((do-work (lambda (x y z)
                  (do-x x)
                  (do-y y)
                  ;; etc
                  )))
  (cond (test-1 (do-work 'a 'b 'c))
        (test-2 (do-work 'i 'j 'k))))

我可以把它全部放在 apply 中(例如,(apply(lambda ...)(cond ...)))但這不是很易讀。有沒有更好的辦法?

最佳答案

與其他lisps(但不是Scheme)一樣,Emacs Lisp具有用於變量和函數的單獨命名空間(即,它是 'Lisp 2 ',而不是'Lisp 1 ';參見功能單元和值單元中分離的技術問題這些術語的來源和含義)。

您需要使用 funcallapply 來調用存儲在變量中的lambda(或其他函數)。

(cond (test-1 (funcall do-work 'a 'b 'c))
      (test-2 (funcall do-work 'i 'j 'k))

如果您始終發送相同數量的參數,請使用 funcall 。如果您需要能夠發送可變數量的參數,請使用 apply

內部機制是每個符號都有多個“單元格”。 使用哪個單元取決於符號在評估中的位置形成。 如果符號是評估表單的第一個元素,請使用“功能”單元格。 在任何其他位置,使用其“值”單元格。 在您的代碼中, do-work 在其值單元格中具有該函數。 要將其作為函數訪問,請使用 funcallapply 。 如果它在函數單元格中,您可以使用其名稱作為評估表單的汽車直接調用它。 您可以使用 flet 來完成此操作或 cl 包中的 labels

轉載註明原文: 如何在Emacs Lisp中創建臨時函數