引入静态变量_Common Lisp变量的一些事情
Lisp-1 vs Lisp-2[1]
Scheme的求值模型非常簡單:只是用一個名字空間,所有表達式中相應(yīng)位置的值應(yīng)該是明確的。
Common Lisp和Scheme最大的不同是,函數(shù)名字空間和數(shù)據(jù)的名字空間是分離的。操作函數(shù)名字空間的語句包括,defun,flet,labels,defmethod和defgeneric等方法。要用函數(shù)名作為另一個函數(shù)的參數(shù)來傳遞函數(shù)時,需要使用function特殊操作符或者使用#' 。
我們稱Scheme的變量模型為Lisp-1,Common Lisp的變量模型是Lisp-2.
綁定
在編程語言中綁定是變量名(變量標(biāo)識符)和對象(保存于內(nèi)存中的存儲單元,數(shù)據(jù)或代碼)的映射關(guān)系。在這個綁定過程中是作用域有密不可分的關(guān)系,作用域決定了哪個變量綁定了哪個存儲單元。
為變量建立綁定之后,就可以通過變量名來引用其所綁定的值。綁定的具體含義,可以參考下圖
詞法作用域(lexical scoping)
詞法作用域又叫靜態(tài)作用域(static scope)。顧名思義,詞法變量即是使用詞法作用域的變量。在詞法作用域里,一個變量的變量名只能在一個函數(shù)或一段代碼區(qū)域( block )內(nèi)存在,此時變量名才會綁定到變量的值。
詞法變量擁有不確定的生存期,即從時間上來講,一個詞法變量可以在任意的時間里持續(xù)存在,取決于該變量需要被使用(reference)多久。 詞法作用域里,對于函數(shù)體中的一個符號,不會逐層檢查函數(shù)的調(diào)用鏈,而是檢查函數(shù)定義時的外部環(huán)境,即捕捉的是函數(shù)定義時該符號的綁定。
動態(tài)作用域(dynamic scoping)
使用動態(tài)作用域的變量叫做動態(tài)(dynamic)變量,有時也叫做特殊(special)變量。動態(tài)作用域里,每個變量名(變量標(biāo)識符)都擁有一個全局的綁定棧。引入一個與動態(tài)變量同名的局部變量會為此變量名創(chuàng)建一個新的變量綁定并將其壓入此變量名的全局綁定棧中,一個全局的變量名(變量標(biāo)識符)總是引用當(dāng)前其棧頂?shù)慕壎?#xff0c;當(dāng)使用該變量綁定的代碼執(zhí)行完畢(即程序控制流離開了此變量的作用域),該變量綁定就會從此變量名的全局綁定棧中被彈出,該變量綁定就失效。
動態(tài)作用域表示的范圍是不確定的,可從任何位置訪問一個動態(tài)變量,取決于它們在什么地方被綁定。動態(tài)變量擁有動態(tài)的生存期。因容易引起誤會而需要注意的是,不確定的作用域和動態(tài)生存期的組合經(jīng)常被錯誤地稱為動態(tài)作用域(dynamic scope)。
動態(tài)作用域里,函數(shù)執(zhí)行遇到一個符號,會由內(nèi)向外逐層檢查函數(shù)的調(diào)用鏈,并打印第一次遇到的那個綁定的值。最外層的綁定即是全局狀態(tài)下的那個值。
Common Lisp的例子
請看下面的代碼
(let ((y 7))(defun foo (x)(print x)(print y)))(let ((y 5))(foo 1))我們通過SLIM執(zhí)行后,可以得到輸出1和7,這說明Common Lisp使用的是詞法作用域。在foo中尋找y的綁定時,它檢查函數(shù)foo的詞法上下文。
再請看下面代碼
(let ((y 7))(defun foo (x)(print x)(print y)(setq y (+ y 2))))(let ((y 5))(foo 1)(foo 1))(let ((y 5))(foo 2))我們通過SLIM執(zhí)行后,我們會看到,1,7,1,9,2和11。在例子中的第一個let表里,定義了一個變量,符號名為y并綁定了值7,那么這個y的作用域就是這個let表區(qū)域。 foo函數(shù)定義在這個區(qū)域內(nèi),其內(nèi)部會使用到一個符號名為y的變量。 那么在詞法作用域的情況下,當(dāng)foo被調(diào)用時,其會查找其定義的環(huán)境有沒有符號名y的變量可以綁定,如果有則把foo中符號y的值綁定,在這里就是7。 并且這里foo中的y和外部let中的y共享一個值,都是對這個值的引用,并不是拷貝了一個新值。
參考
總結(jié)
以上是生活随笔為你收集整理的引入静态变量_Common Lisp变量的一些事情的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: [转载] mac开发者,你不得不知道的环
- 下一篇: kafka java获取topic_通过