在The Swift programming langauge看到closures,但是不太理解是什麼,有什麼樣的特性,能做什麼Objective-C做不到的?編程初學者,求指教
回複內容:
要說 Closure 就得說 Closed Lambda Expression,一個 Closed Lambda Expression 就是沒有自由變數的 Lambda Expression,如
λx. x,而
λx. yx 就不是 Closed。Closed Lambda Expression 最好的性質之一就是它的類型必然同構於某個邏輯重言式,如
λx. λy. xy 的類型就是「肯定前件」
(α → β) → α → β。
那麼如何把某個 Open Lambda Expression 給 Enclose 住呢?答案就是把它引用的所有自由變數給儲存到什麼東西裡面,這種儲存了自由變數的 Lambda Expression 就是 Closure。在其同構的邏輯一面,則是在相繼式左邊加入前提。
文法上東西我就不說了。
電腦程式可以粗略的分成,代碼+資料。初學者很容易就會將這兩者對立起來,會認為代碼就是代碼,資料就是資料,兩者是完全不同的。但實際上,兩者可以統一起來的。將代碼跟資料統一起來,是學習電腦編程的一道門檻。
可以參考,我以前的回答。回呼函數是什嗎?
將資料儲存起來,以後再使用,會覺得很自然。但將代碼保持起來,以後再使用,很多人會覺得很彆扭,難以理解。都是因為還沒有過那道檻。
代碼指令執行時候,會處於一定的環境,單純將代碼儲存下來,還是不夠的,需要將代碼所處的環境也儲存下來。閉包其實是,將代碼跟代碼所處於的環境做為一個整體來看待。周圍的環境,表現為代碼所使用的資料。在有些語言中,這個概念叫代碼塊(block),匿名函數(lambda)等等。
資料跟代碼不再人為割裂開來,統一起來看待。閉包就會是很自然的概念。資料可以傳遞,從一個地方傳遞到另一個地方,並且以後再使用。閉包從某個角度來說,也是資料,當然也可以傳遞,從一個函數傳遞到另一個函數,也可以保持下來,以後再調用。因為將環境也保持下來了,以後調用的時候,就還原當時的情況,順延強制,就很容易,很自然地實現了。而順延強制有什麼作用?就是另一個話題了。
function makeCounter() local count = 0 return function() count = count + 1 return countend
閉包就是一個函數,或者一個指向函數的指標,加上這個函數執行的非局部變數。
說的通俗一點,就是閉包允許一個函數訪問聲明該函數運行上下文中的變數,甚至可以訪問不同運行上文中的變數。
我們用指令碼語言來看一下:
function funA(callback){ alert(callback());}function funB(){ var str = "Hello World"; // 函數funB的局部變數,函數funA的非局部變數 funA( function(){ return str; } );}
Javascript閉包——懂不懂由你,反正我是懂了
這個比較容易懂至少JavaScript閉包是指有權訪問另一個函數範圍中的變數的函數,其他語言的不知道(逃可以和對象的概念對比起來理解,簡單地說:
對象是帶方法的資料,而閉包是帶資料的方法
後半句的資料特指外部資料一塊記憶體地區,存放著可執行代碼和一些變數,指標學過離散沒?在某些集合上某些運算的結果始終在這個集合裡,這就叫閉包性質…………雖然和這個閉包一點關係都沒有=_=。
閉包在函數式語言當中是一個非常有力的工具,但是有點只可意會的感覺。
簡單的來說你可以把閉包看成是綁定了某些變數的值的函數,由於函數式語言中函數是一級對象,所以,這樣的性質就非常有用了,比如說可以通過在函數裡面返回一些閉包來定義一些資料結構什麼的。
舉個栗子:
這是我學common lisp 的時候寫的一個棧
(defun stackpush (stack x) (cons #'(lambda () x) #'(lambda () stack)))(defun stackpop (stack) (apply (cdr stack)nil))(defun stacktop (stack) (apply (car stack) nil))
窮人的類