本文討論閉包的相關概念,大部分代碼使用Swift編寫。Swift對閉包有着良好的支持。這是由於,Swift被設計成一門必定程度上支持函數式編程範式的編程語言。而函數式編程和閉包有着緊密的聯繫。本文着重討論的也是函數式編程和閉包之間的關係。編程
在討論閉包以前,須要先明晰一些簡單的概念。swift
計算機程序語言中必不可少的一部分是它須要提供一種經過名字去使用計算對象的方式。也就是,咱們須要能爲計算對象標識一個名字。名字標識符就是咱們常說的變量,而它的值就是它所對應的那個對象。若是要在編程語言中使用這些變量,咱們就須要有將值和變量名關聯起來,和在須要時又能夠將值提取出來的能力。這就意味着編程語言須要提供某種存儲能力,將變量名和值的對應關係存儲下來,以便須要時使用。數組
將變量名關聯於對應的值,就構成了一個約束。任何變量至多隻能有一個約束。這很容易理解,由於使用變量名取數據時,你固然但願它指明的是明確並且惟一的值。這也是爲什麼把變量名和值的對應關係稱爲約束的緣由。閉包
一系列這種名字和值對應關係(約束)的存儲,就能夠稱之爲環境。環境對於程序語句是相當重要的,由於它肯定了每一個表達式的上下文。甚至,咱們能夠說環境決定了表達式的含義。由於,即使是肯定像(1 + 1)這麼簡單的語句的具體含義,也有賴於環境來肯定+是表達加法的運算符號。咱們能夠假定程序的運行時擁有一個全局環境,這個環境裏包含了全部關聯於基本過程的符號的值。例如,符號+就在全局環境中被約束到基本的加法運算。編程語言
函數,是大部分編程語言都存在的概念。它在不一樣語言中這個概念也存在着細微的區別。在面向對象編程語言中稱之爲「方法」,在函數式編程語言中稱之爲「過程」。不管被稱爲何名字,它們都擁有的共同基本含義是:它是編程語言的一種基本的抽象手段,使咱們能夠將一組操做做爲一個單元組合起來,併爲這組操做命名。這樣咱們就能夠經過一個簡單的名字操做一組複雜的操做。而對於不一樣的編程語言中「函數」這一實體所存在的細微差異,咱們會在後文中經過對「閉包」的探討加以說明。函數式編程
在說閉包以前,須要先清楚「自由變量」的概念。在某個做用域中,若是使用未在本做用域中聲明的變量,對於此做用域來講,該變量就是一個自由變量。函數
閉包,是引用了自由變量的函數。這個被引用的自由變量將和這個函數一同存在,即便已經離開了創造它的環境也不例外。另外一種說法認爲閉包並非函數,而是由函數和與其相關的引用環境組合而成的實體。這是由於,閉包在運行時能夠有多個實例,不一樣的引用環境和相同的函數組合能夠產生不一樣的實例。而函數只會有一個實例。這兩種定義對閉包的見解並無不一樣,只是對函數的定義不一樣。前者對函數的定義更寬鬆,後者則更爲嚴格。設計
原文對象