看到知乎的一個回答,覺得非常不錯,抄下來備份記錄
引用自知乎用戶回答:

鏈接:https://www.zhihu.com/question/21865351/answer/2142927643
來源:知乎
著作權歸作者所有。商業(yè)轉載請聯(lián)系作者獲得授權,非商業(yè)轉載請注明出處。
簡單。
如果函數傳入的不是全局變量,而是一個生命周期比這個函數還短的局部變量,怎么保證這個函數正常運行完。
一般的做法就是隨著這個函數一起保存一個副本嘛。當然各個語言都有自己的做法。還有的語言根本就不支持閉包,函數運行著的時候,變量沒有了,銷毀了。那就報錯唄
-------------------看上面就夠了,下面是一些私貨,可看可不看---------------
擴展一下:閉包的概念來自抽象代數,指的是能讓一個運算閉合的集合。我們編程定義的函數,也是一種運算,如果變量來自外部,那這個運算對于這個函數的環(huán)境來說是不閉合的,因為除了函數的環(huán)境,還依賴變量的環(huán)境。所以我們要在函數的運行的時候,保證運算是閉合的,不管是通過復制變量副本,還是操作指針,還是別的什么辦法,這一系列操作,就是閉包。
再次擴展一下:關于閉合
閉合這個數學概念我覺得很妙。定義不難理解:
封閉性,即閉包(數學)。數學中,若對某個集合的成員進行一種運算,生成的仍然是這個集合的成員,則該集合被稱為在這個運算下閉合。
舉個簡單的例子,減法對于正整數是不閉合的,除法對于整數是不閉合的,開根號對于有理數是不閉合的。如果計算不閉合,就會出現bug,譬如整數的除法出現小數。對于人類來說,這種bug可能會開辟全新的數學領域(人類數學就是這么發(fā)展的),但是對于計算機來說,就是報錯、死機。
閉包的概念,不僅僅是用于保證每一個函數能夠順利運行,還可以被用于計算機語言設計。譬如c#語言的設計就是閉合思維的典范。C#的類庫設計對于低級的、初級的功能閉合,用c#實現較為簡單的功能基本學一兩個小時就可以做出不錯的程序。但如果想用到高級的功能,就必須突破這層閉合,學習使用成本都較高,減少了新手犯錯的幾率,又保留了高手的自由度。再譬如,c++指針為何難用,就是因為指針的運算規(guī)則完全游離于程序規(guī)則,在任何情況下都提供了不閉合的可能性。所以出bug不要太容易。
此外,吐槽一下。編程中的閉包是給面向對象擦屁股的。因為對于值傳遞的編程語言(c語言之類的)根本不存在計算不封閉的問題,變量傳遞都是內存直接復制。
根源上,圖靈機式的順序編程對于值傳遞來說是閉合的,但是對于大量的引用傳遞其實一開始就是不閉合的。所以只要有引用類型的語言,必須要給這種不閉合擦屁股,想辦法處理變量和函數生命周期不一致的問題。這是面向對象的原罪。
浙公網安備 33010602011771號