我需要定義一個名稱包含在另一個變量中的變量。定義一個名稱保存在其他變量中的變量
下面的代碼不起作用,它使用eval
,因此不是很好的風格。
(defvar symbol "zap")
(eval `(defvar ,symbol 100))
(print zap)
我需要定義一個名稱包含在另一個變量中的變量。定義一個名稱保存在其他變量中的變量
下面的代碼不起作用,它使用eval
,因此不是很好的風格。
(defvar symbol "zap")
(eval `(defvar ,symbol 100))
(print zap)
首先 - 你確定你需要這樣做嗎?
現在,有了這樣的方式 -
(defvar *symbol-name* "zap")
(let ((symbol (intern *symbol-name*)))
(proclaim `(special ,symbol))
(setf (symbol-value symbol) 100))
(print |zap|)
注意|zap|
通常需要用水管被引用,因爲intern
是區分大小寫的,而默認readtable upcases符號默認。因此,如果您不引用,如(print zap)
,則將其解釋爲(PRINT ZAP)
,對於zap
錯誤的情況。或者,您可以使用(intern (string-upcase *symbol-name*))
來強化實習符號。
在看到您實際要做的事情後進行更新。
你絕對不想爲此定義全局變量。將鍵(A1 ... H4等)映射到數字的數據結構就是您想要的。在這種情況下,您的密鑰可以是符號或字符串。數據結構可以是散列表,plist或alist(以及其他選項)。例如,一個字符串鍵控的哈希表如下所示:
(defvar *table* (make-hash-table :test #'equalp))
(setf (gethash "A1" *table*) 42)
(print (gethash "A1" *table*)) ==> prints 42
爲此目的使用散列表通常會更好。
如果你絕對想用全局變量來做到這一點,我懷疑SET和SYMBOL-VALUE(以及使用符號而不是字符串)可能會有訣竅。它絕對屬於「嗯,是的,你可以這樣做,但我不相信這是最好的方式」的領土,但。
然而,使用散列表或者(完全跳過存儲空間,如果沒有必要改變A1意味着更深入的行),您最好的辦法是將字母和數字分開並計算相關價值。
我認爲這是有用的原因是:A1..H8是一個數組的入口。由於應用程序(棋盤)產生的原因,此數組必須使用索引0..119。我認爲能夠說方便(setf(aref board a1)'king)等等。但是我也看到,全局命名空間可能不是字段名稱的正確位置。謝謝。 – Patrick 2010-11-09 16:16:45
使用SET:
CL-USER 13 > (defvar *some-symbol* '*this-is-some-symbol*)
*SOME-SYMBOL*
CL-USER 14 > (set *some-symbol* 42)
42
CL-USER 15 > *this-is-some-symbol*
42
,或者如果它是一個字符串:
(setf (symbol-value (find-symbol some-symbol-name)) 42)
我怎麼能忘記,不僅有一個「quoted set」(setq),而且還有通用的「set」指令。有時候我懷疑我的想法很複雜。謝謝,Rainer! – Patrick 2010-11-09 16:23:30
非常感謝你,丹尼爾。我試圖達到的目標是使用名稱爲「A1」..「H8」的64個變量,其中包含值21..98。 A1 = 21,...,H1 = 28,A2 = 31,...,H2 = 38,...,H8 = 98。所以我從(dolist(c'(a b c d e f g h i j))(dolist(r'(1 2 3 4 5 6 7 8))(defvar ...)))開始。這項任務有更好的方法嗎? – Patrick 2010-11-08 16:23:16
是的,你絕對不希望爲此定義一堆全局變量(想象一下,如果你在程序中的某個點使用了一個名爲H1的變量,會發生什麼)。查看更新後的答案。 – 2010-11-08 17:07:40