我想創建一個功能,它允許:一次增加幾個變量,使用&rest?
(incf vara varb varc vard)
而不是
(incf vara) (incf varb) (incf varc) (incf vard)
我不明白的是如何能夠發送更多的參數,如何在一個函數中定義?
(defun定義INC(&休息ARG) (互動) (mapcar「INCF ARG) )
這增加了參數,但ofcourse不保存它們放回變量。
如何去做這件事?
我想創建一個功能,它允許:一次增加幾個變量,使用&rest?
(incf vara varb varc vard)
而不是
(incf vara) (incf varb) (incf varc) (incf vard)
我不明白的是如何能夠發送更多的參數,如何在一個函數中定義?
(defun定義INC(&休息ARG) (互動) (mapcar「INCF ARG) )
這增加了參數,但ofcourse不保存它們放回變量。
如何去做這件事?
它應該工作:
(require 'cl)
(setq a 1)
(setq b 2)
(defun inc (&rest arg)
(interactive)
(mapc (lambda (x) (incf (symbol-value x))) arg))
(inc 'a 'b)
(message "%s %s" a b) => (2 3)
你必須引用,否則每個參數(inc a b)
執行inc
之前變得(inc 1 2)
。
這是你建議做的方式,使用&休息嗎? – PascalVKooten
'&rest'可以讓你不僅僅指出一些參數。其餘的就像'(defun inc(a b)..)'或'(defun inc(a b c)..)'。 – artscan
我建議你使用'dolist'而不是'mapc'。它稍微更高效(字節編譯器不知道如何爲你做轉換)。 – Stefan
如果你希望能夠寫出這種形式(my-incf a b c)
沒有引用變量名a
,b
和c
,使其宏而不是函數:
(defmacro incf+ (&rest vars)
`(progn
,@(mapcar (lambda (var) `(incf ,var)) vars)))
檢查它擴展到正確的代碼使用macroexpand
:
(macroexpand '(incf+ var1 var2 var3))
;; => (progn (incf var1) (incf var2) (incf var3))
由於的Emacs Lisp變量的缺省動態範圍,你可以使用引用變量名稱作爲參數的函數完成了幾乎相同的事情。但宏版本的優點是,由於它在被調用的地方擴展爲代碼,所以它也可以用於詞彙綁定變量。 symbol-value
只適用於動態綁定變量。
您可以通過將下面的文件,加載它(在Emacs 24或更高版本)測試:
;; -*- lexical-binding: t -*-
(defun incf+fun (&rest vars)
(mapC#'(lambda (var) (incf (symbol-value var))) vars))
(defun incf-macro-test()
(let ((a 5) (b 7) (c 11))
(incf+ a b c)
(list a b c)))
(defun incf-function-test()
(let ((a 5) (b 7) (c 11))
(incf+fun 'a 'b 'c)
(list a b c)))
評估(incf-macro-test)
將返回(6 8 12)
,但(incf-function-test)
將與(void-variable a)
錯誤進入調試器。
你或多或少在兩週前問過這個問題。 http://stackoverflow.com/questions/14292227/emacs-defining-a-function-that-sets-arguments-to-0/14293387 – phils