2013-06-26 33 views
2

我使用動態變量時許,我們姑且稱之爲*x*的一個具有10如何通過函數調用有效地在動態變量上使用setf?

我想通過一個函數調用來改變其值的值通過傳遞變量名作爲參數:

(defun change-value (varname) 
    (setf varname 20)) 

然後致電(change-value *x*)。如果我理解正確,varname需要本地範圍,因此setfchange-value之外不起作用。所以,*x*之後仍然是10。

我的問題是,有沒有辦法使*x*等於20通過類似於上面的函數調用?我試着加入(proclaim '(special varname))(declare (special varname)),他們似乎沒有做任何事情。

哦,定義一個宏也或多或少我想要的,但我懷疑這是很好的做法:

(defmacro change-value-macro (varname) 
    `(setf ,varname 20)) 

(change-value-macro *x*) 
+0

'(defun定義變化值的-X(值)(SETF * X *值))'?或者直接'(setf * x * value)'? –

回答

6

定義

(defparameter *x* 10) 
(defun change-value (varname) ; the argument name is misleading! 
    (setf varname 20)) 

,並呼籲(change-value *x*)不買任何東西,因爲change-value是一個函數,你只是通過它10作爲參數;不知道是否涉及*x*。所以,該功能所做的是修改變量varname的本地綁定,將其從10更改爲20並返回後者。

您需要通過symbol(變量名)本身:

(defun change-value (varname) 
    (setf (symbol-value varname) 20)) 

,並把它作爲(change-value '*x*)*x*之前,請注意引號')。

+0

感謝您的回答。現在不會傳遞10作爲參數的結果(setf 10 20)?我們不應該得到一個錯誤? –

+1

@HeitorChang:如果您將未加引號的'* x *'傳遞給我的版本,您將會遇到錯誤。請注意''setf' does not *評估'varname'在你的版本中,所以你不設置10到20,你設置'varname'爲20. – sds

+0

@sds好的,我感謝你的幫助:) –

2

這似乎工作:

(defparameter *x* 'initial) 

(defun change-dyn (variable value) 
    (setf (symbol-value variable) value)) 

(change-dyn '*x* 'final) 
相關問題