lisp 閉包
閉包: 閉包是可以包含自由(未繫結到特定物件)變數的程式碼塊;這些變數不是在這個程式碼塊內或者任何全域性上下文中定義的,而是在定義程式碼塊的環境中定義。“閉包” 一詞來源於以下兩者的結合:要執行的程式碼塊(由於自由變數被包含在程式碼塊中,這些自由變數以及它們引用的物件沒有被釋放)和為自由變數提供繫結的計算環境(作用域)。在 Scheme、Common Lisp、Smalltalk、Groovy、JavaScript、Ruby 和 Python 等語言中都能找到對閉包不同程度的支援。
lisp 裡的閉包 並不是刻意造出來的,而是這種語言自帶的。
例如:
CL-USER> (let ((x 0))
(defun y ()
(incf x 1)))
(let ((x 0))
(defun y ()
(incf x 1)))
Y
CL-USER> (y)
1
CL-USER> (y)
2
CL-USER> (y)
3
CL-USER>
閉包在這裡是用了全域性名稱空間(global namespace)來儲存其自由變數的值。
這帶來的一個好處,就可以用閉包來儲存程式碼裡的私有資訊,而不會暴露給其他程式碼
閉包在lisp 裡的可視性是基於語法的(lexical scope)
lexical scope 的好處是這些繫結在編譯後不需要為其實際分配任何記憶體 slot,
甚至一些顯而易見的邏輯會被直接編譯最佳化成簡單的常量。
閉包在lisp裡可以構造其他oo系統裡的物件或者類的層次,物件變數等等,
在 let over lambda 結構中用 values 返回多個引用了相同 bindings 的 lambdas,可以實現 class 和 object.
下面的是一段抄來的程式碼:
? (let ((password nil)
(secret nil))
(defun set-password (new-passwd)
(if password
'|Can't - already set|
(setq password new-passwd)))
(defun change-password (old-passwd new-passwd)
(if (eq old-passwd password)
(setq password new-passwd)
'|Not changed|))
(defun set-secret (passwd new-secret)
(if (eq passwd password)
(setq secret new-secret)
'|Wrong password|))
(defun get-secret (passwd)
(if (eq passwd password)
secret
'|Sorry|)))
GET-SECRET
? (get-secret 'sesame)
|Sorry|
? (set-password 'valentine)
SECRET
? (set-secret 'sesame 'my-secret)
|Wrong password|
? (set-secret 'valentine 'my-secret)
MY-SECRET
? (get-secret 'fubar)
|Sorry|
? (get-secret 'valentine)
MY-SECRET
? (change-password 'fubar 'new-password)
|Not changed|
? (change-password 'valentine 'new-password)
NEW-PASSWORD
? (get-secret 'valentine)
|Sorry|
; The closed-over lexical variables aren't in the global environment
? password
Error: unbound variable
? secret
Error: unbound variable
; The global environment doesn't affect the closed-over variables
? (setq password 'cheat)
CHEAT
? (get-secret 'cheat)
|Sorry|
lisp 裡的閉包 並不是刻意造出來的,而是這種語言自帶的。
例如:
CL-USER> (let ((x 0))
(defun y ()
(incf x 1)))
(let ((x 0))
(defun y ()
(incf x 1)))
Y
CL-USER> (y)
1
CL-USER> (y)
2
CL-USER> (y)
3
CL-USER>
閉包在這裡是用了全域性名稱空間(global namespace)來儲存其自由變數的值。
這帶來的一個好處,就可以用閉包來儲存程式碼裡的私有資訊,而不會暴露給其他程式碼
閉包在lisp 裡的可視性是基於語法的(lexical scope)
lexical scope 的好處是這些繫結在編譯後不需要為其實際分配任何記憶體 slot,
甚至一些顯而易見的邏輯會被直接編譯最佳化成簡單的常量。
閉包在lisp裡可以構造其他oo系統裡的物件或者類的層次,物件變數等等,
在 let over lambda 結構中用 values 返回多個引用了相同 bindings 的 lambdas,可以實現 class 和 object.
下面的是一段抄來的程式碼:
? (let ((password nil)
(secret nil))
(defun set-password (new-passwd)
(if password
'|Can't - already set|
(setq password new-passwd)))
(defun change-password (old-passwd new-passwd)
(if (eq old-passwd password)
(setq password new-passwd)
'|Not changed|))
(defun set-secret (passwd new-secret)
(if (eq passwd password)
(setq secret new-secret)
'|Wrong password|))
(defun get-secret (passwd)
(if (eq passwd password)
secret
'|Sorry|)))
GET-SECRET
? (get-secret 'sesame)
|Sorry|
? (set-password 'valentine)
SECRET
? (set-secret 'sesame 'my-secret)
|Wrong password|
? (set-secret 'valentine 'my-secret)
MY-SECRET
? (get-secret 'fubar)
|Sorry|
? (get-secret 'valentine)
MY-SECRET
? (change-password 'fubar 'new-password)
|Not changed|
? (change-password 'valentine 'new-password)
NEW-PASSWORD
? (get-secret 'valentine)
|Sorry|
; The closed-over lexical variables aren't in the global environment
? password
Error: unbound variable
? secret
Error: unbound variable
; The global environment doesn't affect the closed-over variables
? (setq password 'cheat)
CHEAT
? (get-secret 'cheat)
|Sorry|
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/133735/viewspace-719927/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 閉包
- 閉包 | 淺談JavaScript閉包問題JavaScript
- Swift-逃逸閉包、自動閉包Swift
- 【集合論】關係閉包 ( 關係閉包求法 | 關係圖求閉包 | 關係矩陣求閉包 | 閉包運算與關係性質 | 閉包複合運算 )矩陣
- PHP 閉包PHP
- JavaScript閉包JavaScript
- Golang閉包Golang
- golang 閉包Golang
- JavaScript 閉包JavaScript
- 理解“閉包”
- Swift 閉包Swift
- Swift,閉包Swift
- 理解閉包
- Swift - 閉包Swift
- JavaScript - 閉包JavaScript
- javascript閉包—圍觀大神如何解釋閉包JavaScript
- 深入理解javascript原型和閉包(15)——閉包JavaScript原型
- [JavaScript閉包]Javascript閉包的判別,作用和示例JavaScript
- js閉包及閉包的經典使用場景JS
- 筆記:閉包筆記
- C#閉包C#
- JS閉包ClosureJS
- 理解JavaScript 閉包JavaScript
- Groovy閉包理解
- Swift-閉包Swift
- JavaScript 清除閉包JavaScript
- js--閉包JS
- JavaScript 的閉包JavaScript
- JavaScript-閉包JavaScript
- 函式閉包函式
- JavaScript之閉包JavaScript
- PHP 閉包(Closure)PHP
- 閉包函式函式
- 閉包 pythonPython
- 解密JavaScript閉包解密JavaScript
- js-閉包JS
- C# 閉包C#
- Javascript 閉包(Closures)JavaScript