我想能夠說(defvar x y)並且綁定到綁定到x而不是x的符號,但defvar只會綁定到符號x,這太糟糕了。我怎麼能沒有默認添加它的符號屬性呢?什麼是lisp的非破壞性版本?
回答
可以使用symbol-value
訪問:
CL-USER> (defvar *sym* 'abc)
*SYM*
CL-USER> (setf (symbol-value *sym*) 100)
100
CL-USER> abc ;non-ANSI-portable, since ABC is undeclared
100
注意,這臺象徵的value cell,這是同它的動態綁定,所以爲了便攜訪問它,您可能需要使用symbol-value
或(本地或全球)聲明變量special
。全球範圍內使用defvar
(不推薦用於非earmuffed符號)
CL-USER> (locally (declare (special abc))
(+ abc 3))
103
或:
CL-USER> (defvar abc)
ABC
(我不知道,其實需要CL實現您可以在本地做這樣的。這一點,雖然你通常是安全的假設未聲明的變量假設默認特)
除了馬蒂亞斯的回答:
你可以還使用set
T1> (defparameter *symbol* 'foo)
*SYMBOL*
T1> (set *symbol* 100)
100
因爲(set symbol value) == (setf (symbol-value symbol) value)
,即在對比setq
和setf
,set
評估其第一個參數。 (setq
可能被解讀爲「set quoted」)set
在Hyperspec中被標記爲廢棄,但由於我不會很快期待下一個CL標準,因此應該可以安全使用。
另外,我不認爲你必須以便攜訪問使用symbol-value
或任何特殊的聲明 - 所有的實際目的,至少。 (雖然人們可能會認爲,從技術上講,因爲即使在本地特殊情況下也不能依賴修改的符號,也許變量不會通過symbol-value
進行評估,但請參閱下面提到的Naggum帖子和Matthias的最後一句。)
確實如此,setq
,setf
,set
et al。只保證修改符合實現的綁定。在頂層使用時,symbol-value
將被修改,但不能依賴任何全局特殊聲明(或其他)發生(參見Naggum)。但通常,實現至少會使用symbol-value
插槽評估新變量。這並不意味着必須使用symbol-value
或本地/全局特殊聲明才能訪問symbol-value
,但它的確實是的意思,即一個新的綁定的相同符號不會自動特殊,因爲它通過defparameter
和朋友介紹的變量就是這種情況。
所以,雖然通常情況下,與全局特殊的變量:
T1> (let ((*symbol* 'bar))
(symbol-value '*symbol*))
BAR
一個新綁定到非全球特別將自身不能是特殊的:
T1> (let ((foo 101)) ; this new binding is lexical
(symbol-value 'foo)) ; so symbol-value refers to the outer special
100
T1> (let ((foo 101))
foo) ; evaluation of foo's new lexical binding
101 ; doesn't look at the `symbol-value`. lexical
; bindings are mere addresses at runtime.
而這也是在可以使用當地的特殊聲明,以便參考foo
的外部(非全局)特別約束:
T1> (let ((foo 101))
foo) ; our new lexical binding
101
T1> (let ((foo 101))
(locally (declare (special foo))
foo)) ; the outer special binding
100
T1> (let ((foo 101))
(setq foo 102) ; modify the new lexical binding
foo)
102
T1> foo ; doesn't modify the outer special binding
100
T1> (let ((foo 101))
(locally (declare (special foo))
(setq foo 102) ; modify the outer special binding
foo))
102
T1> foo
102
據我所知,未定義的部分,或者至少是你應該預料到可移植性問題的部分,是這樣的頂層修改是否可以聲明某些東西(全局)特殊的。我想期望的行爲就是我在這裏展示的,但是如果變量將被全局聲明或者不是(或者甚至可以引入一個頂級詞法變量?),只要它至少在本地是特殊的, t需要本地聲明或symbol-value
來訪問它。
另外,你應該考慮你是否真的需要你所要求的。很可能你想做的事情可以用一種更習慣的方式來解決(至少對於現代的Lispers來說),並且依賴於未定義的行爲不會被REPL使用的任何東西認爲是最好的風格。
- 1. 什麼是java中的破壞性和非破壞性方法?
- 2. lisp中的非破壞性排序?
- 3. 爲什麼ListAppend是非破壞性的,而ArrayAppend和StructInsert都具有破壞性?
- 4. 爲什麼沒有`to_s`的破壞性版本?
- 5. 非破壞性spl_autoload_register
- 6. 什麼是破壞性更新?
- 7. 在破壞性Lisp函數名稱中,「N」是什麼單詞的縮寫?
- 8. npm非破壞性更新
- 9. 歸併 - 破壞性與非破壞性Java中
- 10. Cookie破壞會話破壞,爲什麼?
- 11. 什麼是非破壞性的替代方法存在於類向量中c
- 12. 什麼是非破壞性地向矢量附加值的慣用方式?
- 13. 是CALayer insertSublayer:atindex:破壞性的?
- 14. Ruby中的非破壞性拆分
- 15. OpenGL中的非破壞性濾鏡
- 16. java2d對象的非破壞性轉換
- 17. 非破壞性的全屏mobclix廣告
- 18. mongoid版本不能破壞只是一個單一版本
- 19. 非破壞性的更新,在SQL Server版本金融數據2008
- 20. Javascript中破壞性與非破壞性方法的命名約定
- 21. git中的破壞性命令是什麼?
- 22. 爲什麼UIPreviewActionStyle破壞性標題不是紅色的?
- 23. 什麼是導致包裝破壞?
- 24. 什麼是破壞進程內存?
- 25. 這個破解版的瀏覽器和版本是什麼?
- 26. `Array#first`和`Array#last`的破壞版本
- 27. 非破壞性原子添加?
- 28. PHP - 非破壞性輸入消毒
- 29. AutoMapper非破壞性列表覈對?
- 30. 什麼是Collection + JSON的「版本」屬性
CMU CL _does_實際上是全局聲明一個由'setq' special創建的變量。 (這當然不適用於'(setf symbol-value)'。也許你的意思是這樣;我只是想澄清一下。) –
Matthias:我的意思是,我希望*頂級'setq'是全球特有的還是本地的頂級(我認爲後者更普遍)。在這兩種情況下,人們不必使用「符號值」。但是(這就是我理解你的答案的原因),即使*不能保證,所以從理論上講,必須使用符號值纔是絕對可移植的。 (但那就是我*不會期望的。)也許我的答案的第二部分不夠清晰,但這些例子可能仍然有幫助。重點是可以使用'set',通常不需要'symbol-value'。 – danlei
(「通常,沒有必要使用符號值」僅指這個問題,當然也有使用它的情況。) – danlei