天天看點

詞法作用域(lexical scope) && 動态作用域(dynamic scope)

有詞法作用域的變量叫詞法變量(lexical variable)。

在詞法作用域下,一個符号參照到語境中符号名字出現的地方(可以了解為參照到定義)。局部變量預設有着詞法作用域。

eg:

CL-USER> (let ((x 50))

       (defun foo ()

         x))

FOO

CL-USER> (foo)

50

CL-USER> (let ((x 80))

       (foo))

;Compiler warnings :

;   In an anonymous lambda form: Unused lexical variable X

50

有動态作用域的變量叫特别變量(special variable)。

  (PS.special宣告是獨一無二的,因為它可以改變程式的行為。所有其它的宣告隻是給編譯器的建議;他們或許可以讓一個程式運作得更快,但他們不會改變程式的行為。)

而動态作用域,我們在環境中函數被調用的地方尋找一個變量(可以了解為參照到調用)。全局變量有着動态作用域。

要使一個變量是動态作用域的,我們需要在任何它出現的語境中宣告它是special,如:

CL-USER> (let ((z 12))

       (defun foo ()

         (declare (special z))

         z))

;Compiler warnings :

;   In an anonymous lambda form: Unused lexical variable Z

FOO

CL-USER> (let ((z 19))

       (declare (special z))

       (foo))

當然全局變量就不需要顯著來說明了:

CL-USER> (progn

       (setf r 99)

       (defun foo ()

         r))

;Compiler warnings :

;   In FOO: Undeclared free variable R

FOO

CL-USER> (foo)

99

CL-USER> (setf r 95)

95

CL-USER> (foo)

95

CL-USER> (let ((r 89))

       (foo))

;Compiler warnings :

;   In an anonymous lambda form: Unused lexical variable R

95

CL-USER> (let ((r 89))

       (declare (special r))

       (foo))

89

CL-USER> (progn

       (setf r 66)

       (foo))

66

轉載于:https://www.cnblogs.com/flowjacky/archive/2012/12/26/2834803.html